题目
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;
}
#endif
int main(void)
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef MT
int 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 MT
void 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;
}
#endif
int main(void)
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef MT
int t;
cin >> t;
rep(i, 0, t) solve();
#endif
}