luogu

题意

你有一个\(n*m\)的\(01\)矩阵。你可以把任意一行或者一列的\(01\)取反。求矩阵中最少的\(1\)的数量。

\(n\le20,m\le10^5\)

sol

很自然地有一个\(O(2^nm)\)的暴力:枚举横行的取反情况,然后纵列就取\(01\)数量较少的一者。

我们记状态\(x\)在原矩阵中的出现次数为\(a[x]\),状态中\(01\)较少一者的数量为\(b[x]\)。

会发现当最终的取反状态为\(i\)时,会有\(ans_i=\sum_{j\otimes k=i}a_j*b_k\)。

就是一个异或卷积。FWT即可。

code

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int gi(){
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
#define ll long long
const int N = 1<<20;
const int M = 1e5+5;
int n,m,len;ll a[N],b[N];char s[20][M];
void fwt(ll *P,int opt){
for (int i=1;i<len;i<<=1)
for (int p=i<<1,j=0;j<len;j+=p)
for (int k=0;k<i;++k){
ll x=P[j+k],y=P[j+k+i];
P[j+k]=(x+y)/opt;P[j+k+i]=(x-y)/opt;
}
}
int main(){
n=gi();m=gi();len=1<<n;
for (int i=0;i<n;++i) scanf("%s",s[i]+1);
for (int i=1;i<=m;++i){
int x=0;
for (int j=0;j<n;++j) x=(x<<1)+s[j][i]-'0';
++a[x];
}
for (int i=1;i<len;++i) b[i]=b[i>>1]+(i&1);
for (int i=1;i<len;++i) b[i]=min(b[i],n-b[i]);
fwt(a,1);fwt(b,1);
for (int i=0;i<len;++i) a[i]*=b[i];
fwt(a,2);
ll ans=a[0];
for (int i=1;i<len;++i) ans=min(ans,a[i]);
printf("%I64d\n",ans);return 0;
}

[CF662C]Binary Table的更多相关文章

  1. [CF662C Binary Table][状压+FWT]

    CF662C Binary Table 一道 FWT 的板子-比较难想就是了 有一个 \(n\) 行 \(m\) 列的表格,每个元素都是 \(0/1\),每次操作可以选择一行或一列,把 \(0/1\) ...

  2. CF662C Binary Table【FWT】

    CF662C Binary Table 题意: 给出一个\(n\times m\)的\(01\)矩阵,每次可以反转一行或者一列,问经过若干次反转之后,最少有多少个\(1\) \(n\le 20, m\ ...

  3. CF662C Binary Table 【状压 + FWT】

    题目链接 CF662C 题解 行比较少,容易想到将每一列的状态压缩 在行操作固定的情况下,容易发现每一列的操作就是翻转\(0\)和\(1\),要取最小方案,方案唯一 所以我们只需求出每一种操作的答案 ...

  4. [CF662C] Binary Table(FWT)

    题意: https://www.cnblogs.com/cjyyb/p/9065801.html 题解:

  5. CF662C Binary Table FWT

    传送门 \(N \leq 20\)很小诶 一个暴力的思路是枚举行的翻转状态然后在列上贪心 复杂度为\(O(2^NM)\)显然过不去 考虑到可能有若干列的初始状态是一样的,那么在任意反转之后他们贪心的策 ...

  6. CF662C Binary Table 枚举 FWT

    题面 洛谷题面 (虽然洛谷最近有点慢) 题解 观察到行列的数据范围相差悬殊,而且行的数量仅有20,完全可以支持枚举,因此我们考虑枚举哪些行会翻转. 对于第i列,我们将它代表的01串提取出来,表示为\( ...

  7. CF662C Binary Table (FWT板题)

    复习了一发FWT,发现还挺简单的... 没时间写了,就放一个博客吧:Great_Influence 的博客 注意这一句ans[i]=∑j⊗k=i​f[j]∗dp[k]ans[i]= ∑_{j⊗k=i} ...

  8. CF662C Binary Table (快速沃尔什变换FWT)

    题面 题解 我们会发现,如果单独的一列或一行,它的答案是O1确定的,如果确定了每一行是否变换,那么最后的答案也就简单了许多, 如果确定了行的变换状压下来是x(即x的i位表示第i行是否变换,理解就行), ...

  9. 【CF662C】Binary Table(FWT)

    [CF662C]Binary Table(FWT) 题面 洛谷 CF 翻译: 有一个\(n*m\)的表格(\(n<=20,m<=10^5\)), 每个表格里面有一个\(0/1\), 每次可 ...

随机推荐

  1. Django学习笔记之Ajax入门

    AJAX准备知识:JSON 什么是 JSON ? JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JS ...

  2. Sybase:获取本月最后一天的日期的实现方法

    Sybase:获取本月最后一天的日期的实现方法 Oracle中查询月底那天的日期的函数为:last_day(). 在ASE中没有对应的函数,在Oracle移植到Sybase的时候,需要手动编写函数来实 ...

  3. ubuntu linux 1604 编译安装tesseract-ocr 4.0

    主要参考官方的编译,梳理一下整个流程 Linux The build instructions for Linux also apply to other UNIX like operating sy ...

  4. Windows 修改个性化时间显示

    A goal is a dream with a deadline. Much effort, much prosperity. 我感觉我的时间显示不够人性化.不够个性化 修改注册表 我的系统为Win ...

  5. cf780c

                                                                                             C. Andryush ...

  6. Spring mvc和Servlet

    总结: Servlet:性能最好,处理Http请求的标准. SpringMVC:开发效率高(好多共性的东西都封装好了,是对Servlet的封装,核心的DispatcherServlet最终继承自Htt ...

  7. IE10下阿里旺旺无法快速登录解决办法

    一直都是用Chrome浏览器的,如果已经登录了旺旺,打开淘宝登录的时候都是会有快速登录的,免得手工输入用户名密码了.不经意间用IE10打开淘宝,登录时发现无法使用快速登录,一番研究后发现,IE做了保护 ...

  8. JDK环境变量配置问题 - 原创

    一台电脑上同时装有jdk1.7和jdk1.8,切换jdk时的报错问题 示例如下环境变量: JAVA_HOME       C:\Program Files (x86)\Java\jdk1.7 CLAS ...

  9. linux ioctl()函数

    我这里说的ioctl函数是指驱动程序里的,因为我不知道还有没有别的场合用到了它,所以就规定了我们讨论的范围.写这篇文章是因为我前一阵子被ioctl给搞混了,这几天才弄明白它,于是在这里清理一下头脑. ...

  10. libnetwork 源码浅析

    [编者的话]从docker 1.6开始关注docker网络这块,从原来的铁板一块,到后来的libnetwork拆分,到现在的remote driver,docker 一直在改进.功能缺失,实用性不足, ...