题解 CF662C Binary Table
题意
给定一个
数据范围:
题解
之前听 yls 讲过个不太类似的题,但也是根据本质不同的列的个数较小来做的,这个题就比较有思路。
容易发现取反次数不超过
行数很小,用
有个暴力是枚举每一行是否翻转,状态
这个时间复杂度跟
发现本质不同的列数只有
即
那这个卷积形式不是跑个 FWT 就做完了?
时间复杂度为
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5 + 10, M = (1 << 20) + 10;
int n, m, a[N];
ll f[M], g[M];
char s[N];
void FWT(ll *f, int T) {
for(int mid = 1; mid < n; mid <<= 1)
for(int i = 0; i < n; i += mid << 1)
for(int j = 0; j < mid; j++) {
ll x = f[i + j], y = f[i + j + mid];
f[i + j] = (x + y) / T;
f[i + j + mid] = (x - y) / T;
}
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++) {
scanf("%s", s + 1);
for(int j = 1; j <= m; j++)
if(s[j] - '0') a[j] |= 1 << i;
}
for(int i = 1; i <= m; i++)
f[a[i]]++;
for(int i = 0, w; i < 1 << n; i++) {
w = __builtin_popcount(i);
g[i] = min(w, n - w);
}
n = 1 << n;
FWT(f, 1), FWT(g, 1);
for(int i = 0; i < n; i++)
f[i] *= g[i];
FWT(f, 2);
ll ans = 1e9;
for(int i = 0; i < n; i++)
ans = min(ans, f[i]);
printf("%lld", ans);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话