CF662C Binary Table FWT
\(N \leq 20\)很小诶
一个暴力的思路是枚举行的翻转状态然后在列上贪心
复杂度为\(O(2^NM)\)显然过不去
考虑到可能有若干列的初始状态是一样的,那么在任意反转之后他们贪心的策略肯定是相同的
考虑状压,设\(f_i\)表示初始状态为\(i\)的列的个数,\(g_i\)表示经过行反转,某一列到达\(i\)状态时,这一列留下的最少的\(1\)的可能个数,\(h_i\)表示行翻转状态为\(i\)时的答案
那么\(h_i = \sum\limits_{j\ xor\ k = i}f_jg_k\),是一个异或卷积的形式,FWT即可。
#include<bits/stdc++.h>
using namespace std;
long long cnt1[1 << 20] , mn[1 << 20] , times[1 << 20] , ans[1 << 20] , num[100007] , N , M;
void FWT_xor(long long* arr , int type){
for(int i = 1 ; i < 1 << N ; i <<= 1)
for(int j = 0 ; j < 1 << N ; j += (i << 1))
for(int k = 0 ; k < i ; ++k){
long long x = arr[j + k] , y = arr[i + j + k];
arr[j + k] = x + y;
arr[i + j + k] = x - y;
if(type == -1){
arr[j + k] >>= 1;
arr[i + j + k] >>= 1;
}
}
}
inline char getc(){
char c = getchar();
while(!isdigit(c))
c = getchar();
return c;
}
int main(){
cin >> N >> M;
for(int i = 1 ; i <= N ; ++i)
for(int j = 1 ; j <= M ; ++j)
num[j] = (num[j] << 1) + getc() - 48;
for(int i = 1 ; i <= M ; ++i)
++times[num[i]];
for(int i = 1 ; i < 1 << N ; ++i)
cnt1[i] = cnt1[i - (i & -i)] + 1;
for(int i = 1 ; i < 1 << N ; ++i)
mn[i] = min(cnt1[i] , cnt1[((1 << N) - 1) ^ i]);
FWT_xor(mn , 1);
FWT_xor(times , 1);
for(int i = 0 ; i < 1 << N ; ++i)
ans[i] = mn[i] * times[i];
FWT_xor(ans , -1);
long long all = M * N;
for(int i = 0 ; i < 1 << N ; ++i)
all = min(all , ans[i]);
cout << all;
return 0;
}
CF662C Binary Table FWT的更多相关文章
- [CF662C Binary Table][状压+FWT]
CF662C Binary Table 一道 FWT 的板子-比较难想就是了 有一个 \(n\) 行 \(m\) 列的表格,每个元素都是 \(0/1\),每次操作可以选择一行或一列,把 \(0/1\) ...
- CF662C Binary Table【FWT】
CF662C Binary Table 题意: 给出一个\(n\times m\)的\(01\)矩阵,每次可以反转一行或者一列,问经过若干次反转之后,最少有多少个\(1\) \(n\le 20, m\ ...
- CROC 2016 - Final Round [Private, For Onsite Finalists Only] C. Binary Table FWT
C. Binary Table 题目连接: http://codeforces.com/problemset/problem/662/C Description You are given a tab ...
- CF662C Binary Table 【状压 + FWT】
题目链接 CF662C 题解 行比较少,容易想到将每一列的状态压缩 在行操作固定的情况下,容易发现每一列的操作就是翻转\(0\)和\(1\),要取最小方案,方案唯一 所以我们只需求出每一种操作的答案 ...
- CF662C Binary Table 枚举 FWT
题面 洛谷题面 (虽然洛谷最近有点慢) 题解 观察到行列的数据范围相差悬殊,而且行的数量仅有20,完全可以支持枚举,因此我们考虑枚举哪些行会翻转. 对于第i列,我们将它代表的01串提取出来,表示为\( ...
- CF662C Binary Table (FWT板题)
复习了一发FWT,发现还挺简单的... 没时间写了,就放一个博客吧:Great_Influence 的博客 注意这一句ans[i]=∑j⊗k=if[j]∗dp[k]ans[i]= ∑_{j⊗k=i} ...
- CF662C Binary Table (快速沃尔什变换FWT)
题面 题解 我们会发现,如果单独的一列或一行,它的答案是O1确定的,如果确定了每一行是否变换,那么最后的答案也就简单了许多, 如果确定了行的变换状压下来是x(即x的i位表示第i行是否变换,理解就行), ...
- [CF662C] Binary Table(FWT)
题意: https://www.cnblogs.com/cjyyb/p/9065801.html 题解:
- CodeForces - 662C Binary Table (FWT)
题意:给一个N*M的0-1矩阵,可以进行若干次操作,每次操作将一行或一列的0和1反转,求最后能得到的最少的1的个数. 分析:本题可用FWT求解. 因为其0-1反转的特殊性且\(N\leq20\),将每 ...
随机推荐
- Kotlin入门(2)让App开发变得更容易
上一篇文章介绍了如何搭建Kotlin的开发环境,可是这个开发环境依然基于Android Studio,而在Android Studio上使用Java进行编码,本来就是理所应当的,何必还要专门弄个Kot ...
- 如何将 asp.net core 应用进行 docker 容器部署
asp.net core 部署在 docker 容器中比较简单,但常因asp.net core程序发布的问题造成容器无法正常启动.现在把详细的操作的步骤记录如下: 一.asp.net core web ...
- fedora 28 , firewalld 防火墙控制,firewall-cmd 管理防火墙规则
今天,在使用fedora时,需要修改防火墙规则,一时间忘记了命令是什么,这里进行记录一下. 目前 fedora 28/ centos 7 使用 firewalld 作为防火墙软件:下面我就怎么简单管理 ...
- The resource configuration is not modifiable in this context.
项目中使用了Jersey RESTful 框架, 更新代码后服务能正常起来, 在页面登录时验证码不显示 后台报错 java.lang.IllegalStateException: The resour ...
- Reveal安装
一.安装 第一步:将Reveal.framework拖入工程中(下载地址:http://pan.baidu.com/s/1mgMJVDI,解压后产生的Reveal.framework,拖入工程即可). ...
- SDE ST_Geometry SQL st_intersects查询很慢的解决方法
环境:服务端 SDE 10.0 oracle 11.2,客户端 PLSQL 11,oracle 11.2 为了调试方便,以下测试都是把sql提取出来在PLSQL上做 需求是已知一个多边形的点坐标,要在 ...
- vue实例生命周期详解
每个 Vue 实例在被创建之前都要经过一系列的初始化过程. 例如,实例需要配置数据观测(data observer).编译模版.挂载实例到 DOM ,然后在数据变化时更新 DOM . 在这个过程中,实 ...
- P1141 01迷宫 dfs连通块
题目描述 有一个仅由数字000与111组成的n×nn \times nn×n格迷宫.若你位于一格0上,那么你可以移动到相邻444格中的某一格111上,同样若你位于一格1上,那么你可以移动到相邻444格 ...
- WPFの操作文件浏览框几种方式
方式1: 使用win32控件OpenFileDialog Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog ...
- SHELL-收集Oracle已应用的PSU信息
1. 命令收集版本信息 # 创建数据收集脚本文件 OPER_FILE=${EXECUTE_ID}_oper.sh if [[ "${OPER_USER}" = "${US ...