题目
n*m(n*m<=3e5)的矩阵,
实际为t(t<=1e4)组样例,但保证sum n*m不超过3e5
你可以选一行把所有01翻转,问最多可以让多少列只有一个1,然后把你翻转的行输出
思路来源
其实题还挺裸的,教了一下潘老师,看在这题分数还不低的情况下,写一下题解吧
题解
枚举aij,即枚举一下哪列的哪个数字在答案里,这样其他行翻转的状态是唯一确定的,
哈希记录一下,并记录取得答案的aij,每次转移是o(1)的,只要哈希不冲突即可
单哈希是会被卡的,所以可以双哈希或者mt_19937
代码1(mt_19937)
#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
#define vint vector<int>
#define pii pair<int, int>
#define rep(i, a, b) for (int i = int(a); i < int(b); i++)
#define rng(i, a, b) for (int i = int(a); i <= int(b); i++)
#define per(i, a, b) for (int i = int(b) - 1; i >= int(a); i--)
#define gnr(i, a, b) for (int i = int(b); i >= int(a); i--)
using namespace std;
#define MT
#ifdef MT
void flip(int& c)
{c=!c;
}const int M = 1e9+7;void solve()
{mt19937_64 rnd((unsigned int) chrono::steady_clock::now().time_since_epoch().count());int n, m;cin >> n >> m;vector<string> mp(n);vector<uint64_t> ran(n);ll t = 1;rep(i, 0, n){cin >> mp[i];ran[i]=rnd();}map<uint64_t, int> cnt;pair<int, pair<int,int>> ans = { 0, {0, 0} };rep(i, 0, m){uint64_t hash=0;vint state(n);if (mp[0][i] == '0'){state[0] = 1;hash+=ran[0];}rep(j, 1, n){if (mp[j][i] == '1') {state[j] = 1;hash+=ran[j];}}ans = max(ans, { ++cnt[hash], {i,0}});rep(j, 1, n){hash+=(!state[j-1])*ran[j-1]-state[j-1]*ran[j-1];flip(state[j - 1]);hash+=(!state[j])*ran[j]-state[j]*ran[j];flip(state[j]);ans = max(ans, { ++cnt[hash], {i,j}});}}cout << ans.first << endl;auto [x,y] = ans.second;//cout<<x<<':'<<y<<endl;rep(j,0,n){bool b = mp[j][x]-'0';if((b&&(j!=y)) || ((!b)&&(j==y))){cout<<1;}else{cout<<0;}}cout<<endl;
}
#endifint main(void)
{std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#ifdef MTint t;cin >> t;rep(i, 0, t) solve();
#endif
}
代码2(双哈希)
#include <bits/stdc++.h>
#include <iostream>
#include <map>
#define endl '\n'
#define ll long long
#define vint vector<int>
#define pii pair<int, int>
#define rep(i, a, b) for (int i = int(a); i < int(b); i++)
#define rng(i, a, b) for (int i = int(a); i <= int(b); i++)
#define per(i, a, b) for (int i = int(b) - 1; i >= int(a); i--)
#define gnr(i, a, b) for (int i = int(b); i >= int(a); i--)
using namespace std;
#define MT
#ifdef MTvoid flip(int& c)
{c=!c;
}const int M = 1e9+7,M2=1e9+9;void solve()
{int n, m;cin >> n >> m;vector<string> mp(n);srand(time(NULL));vector<ll> ran(n),ran2(n);ll t = 1, t2=1;rep(i, 0, n){cin >> mp[i];ran[i]=rand()*t%M;ran2[i]=rand()*t2%M2;t<<=1;t2<<=1;t%=M;t2%=M2;}map<pair<ll,ll>, int> cnt;pair<int, pair<int,int>> ans = { 0, {0, 0} };rep(i, 0, m){ll hash=0,hs2=0,cur=0;vint state(n);if (mp[0][i] == '0'){state[0] = 1;hash+=ran[0];hs2+=ran2[0];hash%=M;hs2%=M2;}rep(j, 1, n){if (mp[j][i] == '1') {state[j] = 1;hash+=ran[j];hs2+=ran2[j];hash%=M;hs2%=M2;}}ans = max(ans, { ++cnt[make_pair(hash,hs2)], {i,0}});rep(j, 1, n){hash+=M+(!state[j-1])*ran[j-1]-state[j-1]*ran[j-1];hs2+=M2+(!state[j-1])*ran2[j-1]-state[j-1]*ran2[j-1];hash%=M;hs2%=M2;flip(state[j - 1]);hash+=M+(!state[j])*ran[j]-state[j]*ran[j];hash%=M;hs2+=M2+(!state[j])*ran2[j]-state[j]*ran2[j];hs2%=M2;flip(state[j]);ans = max(ans, { ++cnt[make_pair(hash,hs2)], {i,j}});}}cout << ans.first << endl;auto [x,y] = ans.second;//cout<<x<<':'<<y<<endl;rep(j,0,n){bool b = mp[j][x]-'0';if((b&&(j!=y)) || ((!b)&&(j==y))){cout<<1;}else{cout<<0;}}cout<<endl;
}
#endifint main(void)
{std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#ifdef MTint t;cin >> t;rep(i, 0, t) solve();
#endif
}