codeforces662C FWT

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liufengwei1/article/details/86600933

https://blog.csdn.net/V5ZSQ/article/details/79053445

上面博客通俗易懂,转化巧妙

#include<bits/stdc++.h>
#define maxl 100010

const int mod=1e9+7;

using namespace std;

int n,m,mini,rev;
int ans[1<<20],cnt[1<<20],val[1<<20],num[1<<20];
char ch[21][maxl];

inline int get_val(int x)
{
	int sum=0;
	for(int j=1;j<=n;j++)
	if(x&(1<<(j-1)))
		sum++;
	return min(sum,n-sum);
}

inline void prework()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%s",ch[i]+1);
	for(int i=1;i<=m;i++)
	{
		int x=0;
		for(int j=1;j<=n;j++)
		if(ch[j][i]=='1')
			x|=(1<<(j-1));
		num[x]++;	
	}
	int len=1<<20;
	for(int i=1;i<len;i++)
	{
		cnt[i]=cnt[i>>1]+(i&1);
		val[i]=min(cnt[i],n-cnt[i]);
	}
}

void fwt(int a[],int n)  
{  
    for(int d=1;d<n;d<<=1)  
        for(int m=d<<1,i=0;i<n;i+=m)  
            for(int j=0;j<d;j++)  
            {  
                int x=a[i+j],y=a[i+j+d];  
                //a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod;  
                a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod;  
                //and:a[i+j]=x+y;  
                //or:a[i+j+d]=x+y;  
            }  
}  
  
void ufwt(int a[],int n)  
{  
    for(int d=1;d<n;d<<=1)  
        for(int m=d<<1,i=0;i<n;i+=m)  
            for(int j=0;j<d;j++)  
            {  
                int x=a[i+j],y=a[i+j+d];  
                //a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod;  
                a[i+j]=(1LL*(x+y)*rev)%mod,a[i+j+d]=(1LL*((x-y+mod)%mod)*rev)%mod;  
                //and:a[i+j]=x-y;  
                //or:a[i+j+d]=y-x;  
                //rev表示2在mod下的逆元 
            }  
} 

void solve(int a[],int b[],int len)
{
	fwt(a,len);fwt(b,len);
	for(int i=0;i<len;i++)
		a[i]=1LL*a[i]*b[i]%mod;
	ufwt(a,len);	
}

inline void mainwork()
{
	int len=1<<n;
	solve(num,val,len);
	mini=n*m;
	for(int i=0;i<len;i++)
		mini=min(mini,num[i]);
}

inline void print()
{
	printf("%d",mini);
}

inline int qp(long long a,long long b)
{
	long long ans=1,cnt=a;
	while(b)
	{
		if(b&1)
			ans=(ans*cnt)%mod;
		cnt=(cnt*cnt)%mod;
		b>>=1;
	}
	return ans;
}

int main()
{
	rev=qp(2,mod-2);
	prework();
	mainwork();
	print();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/86600933
FWT