CF662C Binary Table(FWT)
注意到n很小,显然的做法是枚举每行是否翻转,然后O(m)统计Σmin(popcount(ai),n-popcount(ai))即可。考虑将每列是否翻转写成一个二进制数,那么翻转相当于让该二进制数与每列异或。统计每列各种状态的出现次数,将其设为cnt[i],将min(popcount(i),n-popcount(i))设为g[i],可以发现若翻转状态为j,答案即为Σcnt[i]·g[i^j]。这就是一个异或卷积,FWT就行了。
#include<bits/stdc++.h> using namespace std; int getbit(){char c=getchar();while (c<'0'||c>'9') c=getchar();return c^48;} int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N (1<<20) #define M 100010 #define P 1000000007 #define inv2 500000004 int n,m,a[M],cnt[N],g[N],ans; void FWT(int *a,int n,int op) { for (int i=2;i<=n;i<<=1) for (int j=0;j<n;j+=i) for (int k=j;k<j+(i>>1);k++) { int x=a[k],y=a[k+(i>>1)]; a[k]=(x+y)%P,a[k+(i>>1)]=(x-y+P)%P; if (op) a[k]=1ll*a[k]*inv2%P,a[k+(i>>1)]=1ll*a[k+(i>>1)]*inv2%P; } } int main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); const char LL[]="%I64d\n"; #else const char LL[]="%lld\n"; #endif n=read(),m=read(); for (int i=0;i<n;i++) for (int j=1;j<=m;j++) a[j]|=getbit()<<i; for (int i=1;i<=m;i++) cnt[a[i]]++; for (int i=1;i<(1<<n);i++) g[i]=g[i^(i&-i)]+1; for (int i=1;i<(1<<n);i++) g[i]=min(g[i],n-g[i]); FWT(g,(1<<n),0),FWT(cnt,(1<<n),0); for (int i=0;i<(1<<n);i++) g[i]=1ll*g[i]*cnt[i]%P; FWT(g,(1<<n),1); ans=n*m; for (int i=0;i<(1<<n);i++) ans=min(ans,g[i]); cout<<ans; return 0; }
分类:
FWT
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· C# 13 中的新增功能实操
· Ollama本地部署大模型总结
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(4)
· 2025成都.NET开发者Connect圆满结束
· langchain0.3教程:从0到1打造一个智能聊天机器人