C. Binary Table

题目连接:

http://codeforces.com/problemset/problem/662/C

Description

You are given a table consisting of n rows and m columns. Each cell of the table contains either 0 or 1. In one move, you are allowed to pick any row or any column and invert all values, that is, replace 0 by 1 and vice versa.

What is the minimum number of cells with value 1 you can get after applying some number of operations?

Input

The first line of the input contains two integers n and m (1 ≤ n ≤ 20, 1 ≤ m ≤ 100 000) — the number of rows and the number of columns, respectively.

Then n lines follows with the descriptions of the rows. Each line has length m and contains only digits '0' and '1'.

Output

Output a single integer — the minimum possible number of ones you can get after applying some sequence of operations.

Sample Input

3 4

0110

1010

0111

Sample Output

2

Hint

题意

给你一个nm的01矩阵,然后每次操作:你可以挑选任意的某一行或者某一列翻转,然后你需要使得整个矩阵的1的数量尽可能少,问你最少数量是多少。

题解:

首先2^nm这个算法很简单:暴力枚举横着怎么翻转,然后每一列O(1)判断就好了。

然后正解怎么做呢?

我们令ans[i]是异或i之后的1的个数是多少,那么ans[i] = sigma(cnt[i]*num[i^j),cnt[i]表示列那个二进制为i的个数,num[i]表示二进制为i这个数的1的数量是多少。

这个很显然发现 i(ij) = i,这就是一个异或卷积的形式,用FWT加速计算就好了。

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = (1<<20)+6;
int n,m,cnt[maxn];
long long x1[maxn],x2[maxn],ans[maxn];
string s[maxn];
long long t[maxn];
void utfxor(long long a[], int n) {
if(n == 1) return;
int x = n >> 1;
for(int i = 0; i < x; ++ i) {
t[i] = (a[i] + a[i + x]) >> 1;
t[i + x] = (a[i + x] - a[i]) >> 1;
}
memcpy(a, t, n * sizeof(long long));
utfxor(a, x); utfxor(a + x, x);
} long long tmp[maxn]; void tfxor(long long a[], int n) {
if(n == 1) return;
int x = n >> 1;
tfxor(a, x); tfxor(a + x, x);
for(int i = 0; i < x; ++ i) {
tmp[i] = a[i] - a[i + x];
tmp[i + x] = a[i] + a[i + x];
}
memcpy(a, tmp, n * sizeof(long long));
} void solve(long long a[],long long b[],int n)
{
tfxor(a,n);
tfxor(b,n);
for(int i=0;i<n;i++) a[i]=1LL*a[i]*b[i];
utfxor(a,n);
} int main()
{
for(int i=0;i<maxn;i++){
int tmp = i;
while(tmp){
if(tmp&1)cnt[i]++;
tmp>>=1;
}
}
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
cin>>s[i];
for(int i=0;i<m;i++){
int tmp = 0;
for(int j=0;j<n;j++){
if(s[j][i]=='1')tmp+=1<<j;
}
x1[tmp]++;
}
for(int i=0;i<(1<<n);i++)
x2[i]=min(cnt[i],n-cnt[i]);
solve(x1,x2,1<<n);
long long ans = 1e15;
for(int i=0;i<(1<<n);i++)
ans=min(ans,x1[i]);
cout<<ans<<endl;
}

CROC 2016 - Final Round [Private, For Onsite Finalists Only] C. Binary Table FWT的更多相关文章

  1. CROC 2016 - Elimination Round (Rated Unofficial Edition) D. Robot Rapping Results Report 二分+拓扑排序

    D. Robot Rapping Results Report 题目连接: http://www.codeforces.com/contest/655/problem/D Description Wh ...

  2. 8VC Venture Cup 2016 - Final Round (Div. 2 Edition)

    暴力 A - Orchestra import java.io.*; import java.util.*; public class Main { public static void main(S ...

  3. CROC 2016 - Elimination Round (Rated Unofficial Edition) D. Robot Rapping Results Report 拓扑排序+二分

    题目链接: http://www.codeforces.com/contest/655/problem/D 题意: 题目是要求前k个场次就能确定唯一的拓扑序,求满足条件的最小k. 题解: 二分k的取值 ...

  4. CF #CROC 2016 - Elimination Round D. Robot Rapping Results Report 二分+拓扑排序

    题目链接:http://codeforces.com/contest/655/problem/D 大意是给若干对偏序,问最少需要前多少对关系,可以确定所有的大小关系. 解法是二分答案,利用拓扑排序看是 ...

  5. 8VC Venture Cup 2016 - Final Round (Div. 1 Edition) E - Preorder Test 树形dp

    E - Preorder Test 思路:想到二分答案了之后就不难啦, 对于每个答案用树形dp取check, 如果二分的值是val, dp[ i ]表示 i 这棵子树答案不低于val的可以访问的 最多 ...

  6. CROC 2016 - Elimination Round (Rated Unofficial Edition) F - Cowslip Collections 数论 + 容斥

    F - Cowslip Collections http://codeforces.com/blog/entry/43868 这个题解讲的很好... #include<bits/stdc++.h ...

  7. CROC 2016 - Elimination Round (Rated Unofficial Edition) E - Intellectual Inquiry dp

    E - Intellectual Inquiry 思路:我自己YY了一个算本质不同子序列的方法, 发现和网上都不一样. 我们从每个点出发向其后面第一个a, b, c, d ...连一条边,那么总的不同 ...

  8. CROC 2016 - Elimination Round (Rated Unofficial Edition) E. Intellectual Inquiry 贪心 构造 dp

    E. Intellectual Inquiry 题目连接: http://www.codeforces.com/contest/655/problem/E Description After gett ...

  9. CROC 2016 - Elimination Round (Rated Unofficial Edition) C. Enduring Exodus 二分

    C. Enduring Exodus 题目连接: http://www.codeforces.com/contest/655/problem/C Description In an attempt t ...

随机推荐

  1. 浅谈.Net WebService开发

    一.什么是WebService: 简单通俗来说,就是企业之间.网站之间通过Internet来访问并使用在线服务,一些数据,由于安全性问题,不能提供数据库给其他单位使用,这时候可以使   用WebSer ...

  2. 【6_100】Same Tree

    Same Tree Total Accepted: 97481 Total Submissions: 230752 Difficulty: Easy Given two binary trees, w ...

  3. Delphi 的字符及字符串[6] - Char(AnsiChar)、WideChar 与其编码的相互转换

    );    );   {返回: A }  c := Char($41);  {返回: A }end; ];  );     );  {万}  c := WideChar($4E07);  {万}end ...

  4. 安装windows git客户端

    从git官网下载安装包,双击安装,一路默认配置,直到完成 打开git bash,运行 ssh-keygen -t rsa -C "573215750@qq.com" 回车,输入“y ...

  5. 记一次SQLServer数据库误删数据找回

            昨天 同事在本机清理数据库表时,连接到了生产机,误删了二十几张表,幸好是晚上加班的时候删除的,生产机上当时是一天一备份,还原备份是最后的策略,最关键的还是要找回数据.         ...

  6. Print2flash在.NET(C#)中的使用,即文档在线预览

    office文档(word,excel,ppt)在线预览查看,有很多种方式,比如可以 1.调用weboffice组件,进行word预览,要求客户端安装word,仅适用IE, word2013, IE1 ...

  7. C#设计模式——抽象工厂

    一.引言 我相信看到这段文字的人,都具备了良好的技术功底.但是对于自己编写的代码总是充满抱怨,希望能够将自己编写的代码如同房子一般先进行有效 的设计,然后在进行建设.那么这篇文章能够给你一些思路,这里 ...

  8. 【Leetcode】【Medium】Pow(x, n)

    Implement pow(x, n). 解题思路: 求浮点数的幂次方,注意可能为负数次幂: 可以使用二分搜索的思想,当n为偶数时,x^n = x^(n/2) * x^(n/2),因此只需要求得一半的 ...

  9. 优秀的UI插件

    妹子UI: http://amazeui.org/getting-started 百度图表: http://echarts.baidu.com/ 手机UI库:https://github.com/ac ...

  10. SQL Server转发记录指针的坏味道

    什么是转发记录指针? 转发记录指针是堆表中特有的数据存储机制. 当你修改了某个数据页中的一行时,如果该行所在的数据页已经无法存放其修改后的行, SQL Server会把这行数据移动到一个新的数据页上面 ...