标签:lin 行操作 特殊性 pac inline fine using https 暴力枚举
求最终1的最少个数。
可以\(O(m)\)再扫一遍所有列。但显然T飞了。
时间复杂度:\(O(nm+2^nn)\)。
#include <bits/stdc++.h>
#define go(i,a,b) for(i=a;i<b;i++)
using namespace std;
typedef long long ll;
const int N=21,M=1e5+1,S=1<<21;
int i,j,n,m,s,tmp;
char str[M];
bool a[N][M];
ll c[S],e[S],f[S],ans;
void FWT(ll *tf)
{
for(int d=1;d<s;d<<=1)
for(int m=d<<1,i=0;i<s;i+=m)
for(int j=0;j<d;j++)
{
ll x=tf[i+j],y=tf[i+j+d];
tf[i+j]=x+y; tf[i+j+d]=x-y;
}
}
void UFWT()
{
for(int d=1;d<s;d<<=1)
for(int m=d<<1,i=0;i<s;i+=m)
for(int j=0;j<d;j++)
{
ll x=f[i+j],y=f[i+j+d];
f[i+j]=x+y>>1; f[i+j+d]=x-y>>1;
}
}
int main()
{
scanf("%d%d",&n,&m);
go(i,0,n)
{
scanf("%s",str);
go(j,0,m) a[i][j]=str[j]-48;
}
go(i,0,m)
{
s=0;
go(j,0,n) s+=a[j][i]*(1<<j);
c[s]++;
}
s=1<<n;
go(i,0,s)
{
for(tmp=i; tmp; tmp>>=1) e[i]+=tmp&1;
e[i]=min(e[i],n-e[i]);
}
FWT(c); FWT(e);
go(i,0,s) f[i]=c[i]*e[i];
UFWT();
ans=n*m;
go(i,0,s) ans=min(ans,f[i]);
printf("%lld",ans);
}
Codeforces 662C Binary Table(快速沃尔什变换)
标签:lin 行操作 特殊性 pac inline fine using https 暴力枚举
原文地址:https://www.cnblogs.com/Iking123/p/9495603.html