Codeforces 662C(快速沃尔什变换 FWT)
感觉快速沃尔什变换和快速傅里叶变换有很大的区别啊orz
不是很明白为什么位运算也可以叫做卷积(或许不应该叫卷积吧)
我是看 http://blog.csdn.net/liangzhaoyang1/article/details/52819835 里的快速沃尔什变换
这里说一下自己的理解吧,快速傅里叶变换是计算卷积的,就是∑f(x)*g(n-x)这种
快速沃尔什变换也是计算∑f(x)*g(y) ,但这里是计算所有的满足x^y = n(卷积是计算x+y=n)的和
当然,异或也可以换成&,|这些运算符。
正是因为这一点不同,所以fwt与fft有不同的构造方式,具体见引用的博客里的内容
下面说这道题的题解
题意很简单:就是给出一个01矩阵,每一次可以把一行或一列翻转,不限次数,计算最少有多少个1
首先,每一行只需被翻一次或者不翻,可以证明翻奇数次和翻一次等价,不翻和翻偶数次等价
所以就可以先暴力枚举某一行翻没翻,这样有一个m*2^n的复杂度。
那么怎么考虑用fwt呢
考虑一个翻的方案S,实际上第i列答案就是 min(f(S^a[i]), n - f(S^a[i])) (f可以计算1的个数)
所以也就是说,所有的S^a[i]为同一个值的答案是相同的(想一想x^y=n)
那么就处理出来dp[i] = min(f(i), n - f(i))和原矩阵的列中有多少个是i
对于一个方案S, 答案就是∑dp[S^i]*num[i] (注意x^y = S)
所以我们只需要算出dp和num的卷积,然后从中统计答案即可
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- using namespace std;
- typedef long long LL;
- class FWT{
- public:
- void fwt(LL *a, int n){
- for(int d = ; d < n; d <<= ){
- for(int m = d<<, i = ; i < n; i += m){
- for(int j = ; j < d; j++){
- LL x = a[i+j], y = a[i+j+d];
- a[i+j] = x+y; a[i+j+d] = x-y;
- //and a[i+j] = x+y;
- //or a[i+j+d] = x+y;
- }
- }
- }
- }
- void ufwt(LL *a, int n){
- for(int d = ; d < n; d <<= ){
- for(int m = d<<, i = ; i < n; i += m){
- for(int j = ; j < d; j++){
- LL x = a[i+j], y = a[i+j+d];
- a[i+j] = (x+y)/; a[i+j+d] = (x-y)/;
- //and a[i+j] = x-y
- //or a[i+j] = y-x
- }
- }
- }
- }
- void work(LL *a, LL *b, int n){
- fwt(a, n);
- fwt(b, n);
- for(int i = ; i < n; i++) a[i] *= b[i];
- ufwt(a, n);
- }
- }myfwt;
- const int maxn = ;
- char str[maxn];
- LL dp[(<<)+], num[(<<)+], a[maxn];
- int n, m;
- int calc(int x){
- int ans = ;
- for(; x; x >>= ) ans += (x&);
- return ans;
- }
- int main()
- {
- cin>>n>>m;
- for(int i = ; i < n; i++){
- cin>>str;
- for(int j = ; j < m; j++)
- a[j] |= ( (str[j]-'') << i);
- }
- for(int i = ; i < m; i++) num[a[i]]++;
- for(int i = ; i < (<<n); i++){
- int ans = calc(i);
- dp[i] = min(ans, n-ans);
- }
- myfwt.work(dp, num, <<n);
- LL ans = 1e18;
- for(int i = ; i < (<<n); i++) ans = min(ans, dp[i]);
- cout<<ans<<endl;
- return ;
- }
Codeforces 662C(快速沃尔什变换 FWT)的更多相关文章
- 一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记
一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记 曾经某个下午我以为我会了FWT,结果现在一丁点也想不起来了--看来"学"完新东西不经常做题不写博客,就白学了 = = 我没啥智 ...
- 快速沃尔什变换FWT
快速沃尔什变换\(FWT\) 是一种可以快速完成集合卷积的算法. 什么是集合卷积啊? 集合卷积就是在集合运算下的卷积.比如一般而言我们算的卷积都是\(C_i=\sum_{j+k=i}A_j*B_k\) ...
- 集合并卷积的三种求法(分治乘法,快速莫比乌斯变换(FMT),快速沃尔什变换(FWT))
也许更好的阅读体验 本文主要内容是对武汉市第二中学吕凯风同学的论文<集合幂级数的性质与应用及其快速算法>的理解 定义 集合幂级数 为了更方便的研究集合的卷积,引入集合幂级数的概念 集合幂级 ...
- 【学习笔鸡】快速沃尔什变换FWT
[学习笔鸡]快速沃尔什变换FWT OR的FWT 快速解决: \[ C[i]=\sum_{j|k=i} A[j]B[k] \] FWT使得我们 \[ FWT(C)=FWT(A)*FWT(B) \] 其中 ...
- 关于快速沃尔什变换(FWT)的一点学习和思考
最近在学FWT,抽点时间出来把这个算法总结一下. 快速沃尔什变换(Fast Walsh-Hadamard Transform),简称FWT.是快速完成集合卷积运算的一种算法. 主要功能是求:,其中为集 ...
- 快速沃尔什变换 FWT 学习笔记【多项式】
〇.前言 之前看到异或就担心是 FWT,然后才开始想别的. 这次学了 FWT 以后,以后判断应该就很快了吧? 参考资料 FWT 详解 知识点 by neither_nor 集训队论文 2015 集合幂 ...
- HDU 5977 Garden of Eden (树形dp+快速沃尔什变换FWT)
CGZ大佬提醒我,我要是再不更博客可就连一月一更的频率也没有了... emmm,正好做了一道有点意思的题,就拿出来充数吧=.= 题意 一棵树,有 $ n (n\leq50000) $ 个节点,每个点都 ...
- BZOJ4589 Hard Nim(快速沃尔什变换FWT)
这是我第一道独立做出来的FWT的题目,所以写篇随笔纪念一下. (这还要纪念,我太弱了) 题目链接: BZOJ 题目大意:两人玩nim游戏(多堆石子,每次可以从其中一堆取任意多个,不能操作就输).$T$ ...
- 快速沃尔什变换(FWT)学习笔记 + 洛谷P4717 [模板]
FWT求解的是一类问题:\( a[i] = \sum\limits_{j\bigoplus k=i}^{} b[j]*c[k] \) 其中,\( \bigoplus \) 可以是 or,and,xor ...
随机推荐
- MFC下的DLL编程学习
1.DLL库与LIB库对比: 静态链接库Lib(Static Link Library),是在编译的链接阶段将库函数嵌入到应用程序的内部.如果系统中运行的多个应用程序都包含所用到的公共库函数,则必然造 ...
- 【c学习-12】
/*枚举*/ #include void enumFunction(){ enum enum_var{"a","b",1,2}; enum{"c&qu ...
- js-scroll判断页面是向上滚动还是向下滚动
原理:那当前的scrollTop和之前的scrollTop对比 如果变大了,表示向下滚动(scrollTop值变大): 如果变小了,表示向上滚动(scrollTop值变小). 方法一:js代码: $( ...
- 三、css篇
#这里强烈推荐一本书<css世界>,css第一书. #上面的层叠顺序得记住. 1.align-items justify-content 是flex(弹性盒模型)必须要会的属性,alig ...
- 更新Composer依赖报错处理Fatal error: Declaration of Fxp\Composer\AssetPlugin\Repository\AbstractAssetsRe
更新Composer依赖报错处理 Fatal error: Declaration of Fxp\Composer\AssetPlugin\Repository\AbstractAssetsRe po ...
- 腾讯招聘网数据爬取存入mongodb
#!/user/bin/env python3 # -*- coding: utf-8 -*- import requests from lxml import etree from math imp ...
- Python tips(
(此文是在实际工程中遇到的一些小问题,给予解决和整理.解决方法大多来自网上零散的文章.有一个系统化的Python问题解决方案,来自<Python 3 学习笔记>雨痕著,其中对Python的 ...
- kettle 遇到 解决Incorrect integer value: '' for column 'id' at row 1 完美解决-费元星
最近自己在测试一个开源的程序,测试中发现.该程序都添加和更新的时候回出现 Incorrect integer value: '' for column 'id' at row 1类是的错误! 后来我自 ...
- 使用PSSH批量操作Linux服务器
简介 服务器多了,有一个问题就是如何批量快速操作多台服务器,在网上搜到了PSSH工具,试用了一下发现挺好用,推荐给大家. pssh是一个python编写的可以在多台服务器上执行命令的轻量级管理工具,同 ...
- 位运算 & 网络序字节序
一.初识位运算 位运算,见词明意,二进制运算,通常需要将运算数转换为二进制再进行处理,如果是在程序语言中则无需自己进行进制转换,基本的位操作符有如下几种:与(&).或(|).异或(^).取反( ...