CF662C Binary Table (FWT板题)

复习了一发FWT,发现还挺简单的。。。

没时间写了,就放一个博客吧:Great_Influence 的博客

注意这一句ans[i]=jk=if[j]dp[k]ans[i]= ∑_{j⊗k=i} ​ f[j]∗dp[k]

本来应该是ji=kj⊗i=k,变一下就是jk=ij⊗k=i

然后就是板子了

好强。。

CODE

#include <bits/stdc++.h>
using namespace std;
const int MAXS = 1<<20;
const int MAXN = 20;
const int MAXM = 100005;
typedef long long LL;
int n, m, a[MAXM], bit[MAXS];
LL f[MAXS], dp[MAXS];
inline void FWT(LL arr[], int len, int flg) {
	LL x, y;
	for(int i = 2; i <= len; i<<=1)
		for(int j = 0; j < len; j += i)
			for(int k = j; k < j + i/2; ++k) {
				x = arr[k], y = arr[k + i/2];
				if(~flg) arr[k] = x + y, arr[k + i/2] = x - y;
				else arr[k] = (x + y) >> 1, arr[k + i/2] = (x - y) >> 1;
			}
}
char s[MAXM];
int main () {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++i) {
		scanf("%s", s+1);
		for(int j = 1; j <= m; ++j)
			a[j] = (a[j]<<1)|(s[j]=='1');
	}
	for(int i = 1; i <= m; ++i) ++f[a[i]];
	for(int s = 0; s < (1<<n); ++s) bit[s] = bit[s>>1] + (s&1);
	for(int s = 0; s < (1<<n); ++s) dp[s] = min(bit[s], bit[s^((1<<n)-1)]);
	FWT(f, 1<<n, 1), FWT(dp, 1<<n, 1);
	for(int i = 0; i < (1<<n); ++i) f[i] *= dp[i];
	FWT(f, 1<<n, -1);
	LL ans = n*m;
	for(int i = 0; i < (1<<n); ++i) ans = min(ans, f[i]);
	printf("%I64d
", ans);
}
原文地址:https://www.cnblogs.com/Orz-IE/p/12039270.html