「CF662C」 Binary Table

「CF662C」 Binary Table

题目链接

题目所给的 \(n\) 很小,于是我们可以考虑这样一种朴素做法:暴力枚举第 \(i\) 行是否翻转,这样每一行的状态就确定了,这时取每一列 \(0/1\) 个数较小的数字即可(因为每一列也可以翻转)。这样的时间复杂度是 \(O(m\cdot2^n)\)。

但是显然这样过不了。

我们发现表格的具体行列对我们的答案是没有影响的。即我们只需要知道状态为 \(x\) 的行或者状态为 \(x\) 的列的个数即可。由于 \(n\le20\),这启发我们对于每一列进行状态压缩。

于是我们定义:\(f_S\) 表示列状态为 \(S\) 的列的个数,同时定义 \(g_S\) 为 列状态为 \(S\) 的列中 \(0/1\) 个数中小的一个。显然 \(f,g\) 两个数组都可以在可以接受的时间范围内预处理出来。

对于翻转情况,我们用一个数 \(x\) 表示,若二进制下第 \(i\) 位为 \(1\), 则代表第 \(i\) 行翻转。

于是有当翻转状态为 \(x\) 时,有
\[
Ans_x=\sum_{i=0}^{2^n-1}f_ig_{i\oplus x}
\]
其中 \(\oplus\) 代表按位异或。

简单变形,我们可以得到
\[
Ans_x=\sum_{i=0}^{2^n-1}\sum_{j=0}^{2^n-1}[i\oplus x=j]f_ig_j
\]
由于异或具有交换律,于是有
\[
Ans_x=\sum_{i=0}^{2^n-1}\sum_{j=0}^{2^n-1}[i\oplus j=x]f_ig_j
\]
这就是集合幂卷积中异或卷积的标准形式,直接使用 \(\texttt{FWT}\) 优化计算即可。时间复杂度为 \(O(n2^n)\)。

代码很简洁,如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+5;
long long num[maxn],f[maxn],g[maxn];
int n,m;
inline void XOR(long long *f,int tmp){
    for(int o=2,k=1;o<=n;o<<=1,k<<=1){
        for(int i=0;i<n;i+=o){
            for(int j=0;j<k;++j){
                long long a=f[i+j],b=f[i+j+k];
                if(tmp) f[i+j]=a+b,f[i+j+k]=a-b;
                else f[i+j]=(a+b)>>1,f[i+j+k]=(a-b)>>1;
            }
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            int x;scanf("%1d",&x);
            num[j]+=x*(1<<i-1);
        }
    }
    for(int i=1;i<=m;++i) ++f[num[i]];
    for(int i=1;i<(1<<n);++i){
        int x=i;
        while(x) x=(x-1)&x,++g[i];
        g[i]=min(g[i],n-g[i]);
    }
    n=(1<<n);
    XOR(f,1),XOR(g,1);
    for(int i=0;i<n;++i) f[i]=f[i]*g[i];
    XOR(f,0);
    long long ans=(1<<30);
    for(int i=0;i<n;++i) ans=min(ans,f[i]);
    printf("%lld\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/HenryHuang-Never-Settle/p/solution-CF622C.html

时间: 2024-10-29 11:35:01

「CF662C」 Binary Table的相关文章

【CF662C】Binary Table 按位处理

[CF662C]Binary Table 题意:给你一个$n\times m$的01网格,你可以进行任意次操作,每次操作是将一行或一列的数都取反,问你最多可以得到多少个1? $n\le 20,m\le 10^5$ 题解:我也不知道叫啥了,说状压也不对,说fwt也不太对,就叫按位处理得了. 显然有$O(2^nm)$暴力,先枚举每行是否取反,然后枚举每列,如果0多就取反,否则不取. 但我们发现我们完全可以将本质相同的列一起处理,什么叫本质相同的列呢?假如我们对每行是否取反的状态为S,则所有$xor

【CF662C】Binary Table(FWT)

[CF662C]Binary Table(FWT) 题面 洛谷 CF 翻译: 有一个\(n*m\)的表格(\(n<=20,m<=10^5\)), 每个表格里面有一个\(0/1\), 每次可以将一行或者一列的\(01\)全部翻转 回答表格中最少有多少个\(1\) 题解 发现\(n\)很小,\(m\)很大 状压是跑不掉了 如果我们确定翻转哪些行,那么答案唯一确定(贪心的选每一列中\(0/1\)的较小值) 相同的列显然可以合并, 把每一列按照\(01\)状压,记\(a[i]\)为状态为\(i\)的列

【CF662C】Binary Table

题目 好吧,我连板子都不会了 有一个非常显然的做法就是\(O(2^nm)\)做法就是枚举每一行的状态,之后我们贪心去看看每一列是否需要翻转就好啦 显然这个做法非常垃圾过不去 首先我们发现每一列都不超过\(20\),考虑把每一列都压成一个状态 我们考虑设一些奇怪的东西 设\(g_i\)表示行的翻转状态为\(i\)的最优解,\(f_i\)表示有多少列的状态为\(i\),\(dp_i\)表示\(i\)这个状态最少有多少个\(1\) 显然\(dp_i=min\{bit(i),n-bit(i)\}\) 我

CF662C Binary Table

LINK:CF662C Binary Table 一个nm的表格 每个元素都是0/1 每次操作可以选择一行或一列 将0/1翻转.可以操作无限次. 问最终局面最少有多少个1.\(n\leq 20,m\leq 100000\) 可以发现 先翻列再翻行等价于先翻行再翻列 先翻行再翻列再翻行 如果行是相同的 等价于翻列 反之同上一种情况. 对于任意一对行列之间的关系只有上述的几种情况 故可以发现 最优操作可以转换成 先翻行再翻列. 之所以这样是发现了行数较少 暴力枚举行的状态. 此时只有列能翻了 每一列

大数据和「数据挖掘」是何关系?---来自知乎

知乎用户,互联网 244 人赞同 在我读数据挖掘方向研究生的时候:如果要描述数据量非常大,我们用Massive Data(海量数据)如果要描述数据非常多样,我们用Heterogeneous Data(异构数据)如果要描述数据既多样,又量大,我们用Massive Heterogeneous Data(海量异构数据)--如果要申请基金忽悠一笔钱,我们用Big Data(大数据) 编辑于 2014-02-2817 条评论感谢 收藏没有帮助举报作者保留权利 刘知远,NLPer 4 人赞同 我觉得 大数据

从「集装箱」思考Docker风潮

从「集装箱」思考Docker风潮 -- Docker潮流下的赢家策略 By 高焕堂 (台灣Docker聯盟 主席) 2015/02/20 前言 在许多革命性转折里,经常出现集装箱的身影:它就像幸运草一般,总是带来许多幸福和财运.现在Docker风起云涌,再现集装箱身影,如果开放视野.大力支持它,持续发挥它的潜能和力量,则幸运草就会出现在我们身旁了. 由于Docker集装箱带来的商机,其最直接的受益者是软件管理者(或称维运者),例如软件测试工具业者.测试人员等.因此在今天,不论您是开发者或是维运者

laravel4 「时间戳」问题

默认 Eloquent 会自动维护数据库表的 created_at 和 updated_at 字段.只要把这两个「时间戳」字段加到数据库表, Eloquent 就会处理剩下的工作.如果不想让 Eloquent 自动维护这些字段,把下面的属性加到模型类里: 关闭自动更新时间戳 class User extends Eloquent { protected $table = 'users'; public $timestamps = false; } 自定义时间戳格式 如果想要自定义时间戳格式,可以

「笔记」「ubuntu」mint个人shell样式脚本

alias ll='ls -al' use_color=false # Set colorful PS1 only on colorful terminals.# dircolors --print-database uses its own built-in database# instead of using /etc/DIR_COLORS.  Try to use the external file# first to take advantage of user additions. 

零元学Expression Blend 4 - Chapter 8 用实例了解布局容器系列-「Grid」

原文:零元学Expression Blend 4 - Chapter 8 用实例了解布局容器系列-「Grid」 本系列将教大家以实做案例认识Blend 4 的布局容器,此章介绍的是Blend 4 里的布局容器大哥-「Grid」. ? 本系列将教大家以实做案例认识Blend 4 的布局容器,此章介绍的是Blend 4 里的布局容器大哥-「Grid」. ? ? ? 就是要让不会的新手都看的懂! ? ? ? <实至名归的容器大哥> Blend 4内的容器有很多种,比较常运用到的除了有Grid.Can