感觉快速沃尔什变换和快速傅里叶变换有很大的区别啊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的卷积,然后从中统计答案即可

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. using namespace std;
  5. typedef long long LL;
  6. class FWT{
  7. public:
  8. void fwt(LL *a, int n){
  9. for(int d = ; d < n; d <<= ){
  10. for(int m = d<<, i = ; i < n; i += m){
  11. for(int j = ; j < d; j++){
  12. LL x = a[i+j], y = a[i+j+d];
  13. a[i+j] = x+y; a[i+j+d] = x-y;
  14. //and a[i+j] = x+y;
  15. //or a[i+j+d] = x+y;
  16. }
  17. }
  18. }
  19. }
  20. void ufwt(LL *a, int n){
  21. for(int d = ; d < n; d <<= ){
  22. for(int m = d<<, i = ; i < n; i += m){
  23. for(int j = ; j < d; j++){
  24. LL x = a[i+j], y = a[i+j+d];
  25. a[i+j] = (x+y)/; a[i+j+d] = (x-y)/;
  26. //and a[i+j] = x-y
  27. //or a[i+j] = y-x
  28. }
  29. }
  30. }
  31. }
  32. void work(LL *a, LL *b, int n){
  33. fwt(a, n);
  34. fwt(b, n);
  35. for(int i = ; i < n; i++) a[i] *= b[i];
  36. ufwt(a, n);
  37. }
  38. }myfwt;
  39. const int maxn = ;
  40. char str[maxn];
  41. LL dp[(<<)+], num[(<<)+], a[maxn];
  42. int n, m;
  43. int calc(int x){
  44. int ans = ;
  45. for(; x; x >>= ) ans += (x&);
  46. return ans;
  47. }
  48. int main()
  49. {
  50. cin>>n>>m;
  51. for(int i = ; i < n; i++){
  52. cin>>str;
  53. for(int j = ; j < m; j++)
  54. a[j] |= ( (str[j]-'') << i);
  55. }
  56. for(int i = ; i < m; i++) num[a[i]]++;
  57. for(int i = ; i < (<<n); i++){
  58. int ans = calc(i);
  59. dp[i] = min(ans, n-ans);
  60. }
  61. myfwt.work(dp, num, <<n);
  62. LL ans = 1e18;
  63. for(int i = ; i < (<<n); i++) ans = min(ans, dp[i]);
  64. cout<<ans<<endl;
  65. return ;
  66. }

Codeforces 662C(快速沃尔什变换 FWT)的更多相关文章

  1. 一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记

    一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记 曾经某个下午我以为我会了FWT,结果现在一丁点也想不起来了--看来"学"完新东西不经常做题不写博客,就白学了 = = 我没啥智 ...

  2. 快速沃尔什变换FWT

    快速沃尔什变换\(FWT\) 是一种可以快速完成集合卷积的算法. 什么是集合卷积啊? 集合卷积就是在集合运算下的卷积.比如一般而言我们算的卷积都是\(C_i=\sum_{j+k=i}A_j*B_k\) ...

  3. 集合并卷积的三种求法(分治乘法,快速莫比乌斯变换(FMT),快速沃尔什变换(FWT))

    也许更好的阅读体验 本文主要内容是对武汉市第二中学吕凯风同学的论文<集合幂级数的性质与应用及其快速算法>的理解 定义 集合幂级数 为了更方便的研究集合的卷积,引入集合幂级数的概念 集合幂级 ...

  4. 【学习笔鸡】快速沃尔什变换FWT

    [学习笔鸡]快速沃尔什变换FWT OR的FWT 快速解决: \[ C[i]=\sum_{j|k=i} A[j]B[k] \] FWT使得我们 \[ FWT(C)=FWT(A)*FWT(B) \] 其中 ...

  5. 关于快速沃尔什变换(FWT)的一点学习和思考

    最近在学FWT,抽点时间出来把这个算法总结一下. 快速沃尔什变换(Fast Walsh-Hadamard Transform),简称FWT.是快速完成集合卷积运算的一种算法. 主要功能是求:,其中为集 ...

  6. 快速沃尔什变换 FWT 学习笔记【多项式】

    〇.前言 之前看到异或就担心是 FWT,然后才开始想别的. 这次学了 FWT 以后,以后判断应该就很快了吧? 参考资料 FWT 详解 知识点 by neither_nor 集训队论文 2015 集合幂 ...

  7. HDU 5977 Garden of Eden (树形dp+快速沃尔什变换FWT)

    CGZ大佬提醒我,我要是再不更博客可就连一月一更的频率也没有了... emmm,正好做了一道有点意思的题,就拿出来充数吧=.= 题意 一棵树,有 $ n (n\leq50000) $ 个节点,每个点都 ...

  8. BZOJ4589 Hard Nim(快速沃尔什变换FWT)

    这是我第一道独立做出来的FWT的题目,所以写篇随笔纪念一下. (这还要纪念,我太弱了) 题目链接: BZOJ 题目大意:两人玩nim游戏(多堆石子,每次可以从其中一堆取任意多个,不能操作就输).$T$ ...

  9. 快速沃尔什变换(FWT)学习笔记 + 洛谷P4717 [模板]

    FWT求解的是一类问题:\( a[i] = \sum\limits_{j\bigoplus k=i}^{} b[j]*c[k] \) 其中,\( \bigoplus \) 可以是 or,and,xor ...

随机推荐

  1. mysql计算排名

    mysql计算排名,获取行号rowno 学生成绩表数据 SELECT * FROM table_score ORDER BY score DESC; 获取某个学生成绩排名并计算该学生和上一名学生成绩差 ...

  2. LINUX SSH 建立密钥对

    配置私钥和公钥 先检查一下服务器的ssh配置文件 /etc/ssh/sshd_config RSAAuthentication yes # 启用 RSA 认证 默认为 yes PubkeyAuthen ...

  3. 如何导入XML数据 (python3.6.6区别于python2 环境)

    1.在python2中 代码如下图: 放在python3 环境下执行,将出现如下错误: 原因: python2中形如myTree.keys()[0]这样的写法是没有问题的,因为myTree.keys( ...

  4. Python的jieba模块简介

    现如今,词云技术遍地都是,分词模块除了jieba也有很多,主要介绍一下jieba的基本使用 import jieba import jieba.posseg as psg from os import ...

  5. C语言实现简易扫雷

    首先,写代码之前要将整体思路写出来: 扫雷游戏:1.需要两个二维数组,一个用来展示,一个用来放雷; 2.整体骨架在代码中都有注释说明; 3.游戏难度比较简单,适合初学者观看,如果有大佬看明白,可以指点 ...

  6. go学习笔记-面向对象(Methods, Interfaces)

    面向对象(Methods, Interfaces) Method method是附属在一个给定的类型上的,他的语法和函数的声明语法几乎一样,只是在func后面增加了一个receiver(也就是meth ...

  7. Educational Codeforces Round 47 (Rated for Div. 2) :D. Relatively Prime Graph

    题目链接:http://codeforces.com/contest/1009/problem/D 解题心得: 题意就是给你n个点编号1-n,要你建立m条无向边在两个互质的点之间,最后所有点形成一个连 ...

  8. MyBatis的笔记

    1.#{}和${}的区别是什么? #{}是预编译处理,${}是字符串替换. #{}是sql的参数占位符,${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替 ...

  9. LeetCode:22. Generate Parentheses(Medium)

    1. 原题链接 https://leetcode.com/problems/generate-parentheses/description/ 2. 题目要求 给出一个正整数n,请求出由n对合法的圆括 ...

  10. elasticsearch 关联查询

    父-子关系文档 父-子关系文档 在实质上类似于 nested model :允许将一个对象实体和另外一个对象实体关联起来. 而这两种类型的主要区别是:在 nested objects 文档中,所有对象 ...