解决涉及子集配凑的卷积问题

一、介绍

1.基本用法

FWT快速沃尔什变换学习笔记

就是解决一类问题:

$f[k]=\sum_{i\oplus j=k}a[i]*b[j]$

基本思想和FFT类似。

首先转化成为另一个多项式$FWT(A),FWT(B)$

使得:$FWT(A\oplus B)=FWT(A)×FWT(B)$

这里,$×$是按位乘。这个是$O(n)$的。

然后,再$IFWT$回去即可。

类似于,直接过马路不好走。先从左边走上一座天桥,再从天桥走过去,再到马路右侧走下天桥。

就变成了$O(nlogn)$

$FWT$虽然不是非常容易理解,但是比较容易记忆。

(虽然一定要理解)

类比$FFT$的写法,就可以比较轻松记忆。

就是分治压缩、合并、分治解压的过程。

【模板】快速沃尔什变换

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
il void prin(int x){
if(x/) prin(x/);
putchar(x%+'');
}
namespace Miracle{
const int N=+;
const int mod=;
const int inv2=;
int a[N],b[N];
int c[N],d[N];
int e[N];
int n;
void _or(int *f,int op){
for(reg p=;p<=n;p<<=){
int len=p/;
for(reg k=;k<n;k+=p){
for(reg l=k;l<k+len;++l){
if(op==)f[l+len]=(f[l+len]+f[l])%mod;
else f[l+len]=(f[l+len]-f[l]+mod)%mod;
}
}
}
}
void _and(int *f,int op){
for(reg p=;p<=n;p<<=){
int len=p/;
for(reg k=;k<n;k+=p){
for(reg l=k;l<k+len;++l){
if(op==)f[l]=(f[l+len]+f[l])%mod;
else f[l]=(f[l]-f[l+len]+mod)%mod;
}
}
}
}
void _xor(int *f,int op){
for(reg p=;p<=n;p<<=){
int len=p/;
for(reg k=;k<n;k+=p){
for(reg l=k;l<k+len;++l){
int x=f[l],y=f[l+len];
if(op==){
f[l]=(x+y)%mod;
f[l+len]=(x-y+mod)%mod;
}
else{
f[l]=(ll)(x+y)*inv2%mod;
f[l+len]=(ll)(x-y+mod)%mod*inv2%mod;
}
}
}
}
}
int main(){
scanf("%d",&n);
n=(<<n);
for(reg i=;i<n;++i) rd(a[i]),c[i]=a[i];
for(reg i=;i<n;++i) rd(b[i]),d[i]=b[i]; _or(c,);_or(d,);
for(reg i=;i<n;++i) e[i]=(ll)c[i]*d[i]%mod;
_or(e,-);
for(reg i=;i<n;++i){
prin(e[i]);putchar(' ');c[i]=a[i],d[i]=b[i];
}putchar('\n'); _and(c,);_and(d,);
for(reg i=;i<n;++i) e[i]=(ll)c[i]*d[i]%mod;
_and(e,-);
for(reg i=;i<n;++i){
prin(e[i]);putchar(' ');c[i]=a[i],d[i]=b[i];
}putchar('\n'); _xor(c,);_xor(d,);
for(reg i=;i<n;++i) e[i]=(ll)c[i]*d[i]%mod;
_xor(e,-);
for(reg i=;i<n;++i){
prin(e[i]);putchar(' ');//c[i]=a[i],d[i]=b[i];
}putchar('\n');
return ;
} }
int main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2018/11/22 15:08:15
*/

模板

2.子集卷积

https://www.cnblogs.com/Dance-Of-Faith/p/8818211.html

多加一维i,强制记录涉及集合sz大小

外层枚举sz

O(2^n*n^2)

(推荐使用FWT,因为比FMT常数小)

二、例题

留坑

安师大附中集训 Day2

[FWT] UOJ #310. 【UNR #2】黎明前的巧克力

三、FFT、NTT、FWT的比较

留坑

没啥可比较的。处理思路一致。

就是运算符的问题吧。

四、FWT、FMT的比较

留坑

FMT好写,FWT的与或卷积的第一步可以取代FMT


upda:2019.4.17

FMT可以代替FWT的与或卷积。IFMT把+改成-即可

(xor暂时不知道具体含义,估计也可以代替?)

实际上

FMT很辣鸡

相比之下,FWT做的事情完全包含FMT,并且常数是FMT的1/2!

[WC2018]州区划分(这个题我人傻常数大,必须用FWT卡常才能过)

所以还是写FWT吧

[学习笔记]FWT——快速沃尔什变换的更多相关文章

  1. FWT快速沃尔什变换学习笔记

    FWT快速沃尔什变换学习笔记 1.FWT用来干啥啊 回忆一下多项式的卷积\(C_k=\sum_{i+j=k}A_i*B_j\) 我们可以用\(FFT\)来做. 甚至在一些特殊情况下,我们\(C_k=\ ...

  2. 浅谈算法——FWT(快速沃尔什变换)

    其实FWT我啥都不会,反正就是记一波结论,记住就好-- 具体证明的话,推荐博客:FWT快速沃尔什变换学习笔记 现有一些卷积,形如 \(C_k=\sum\limits_{i\lor j=k}A_i*B_ ...

  3. Django RF:学习笔记(8)——快速开始

    Django RF:学习笔记(8)——快速开始 安装配置 1.使用Pip安装Django REST Framework: pip install djangorestframework 2.在Sett ...

  4. [学习笔记]NTT——快速数论变换

    先要学会FFT[学习笔记]FFT——快速傅里叶变换 一.简介 FFT会爆精度.而且浮点数相乘常数比取模还大. 然后NTT横空出世了 虽然单位根是个好东西.但是,我们还有更好的东西 我们先选择一个模数, ...

  5. 【学习笔记】快速傅里叶变换(FFT)

    [学习笔记]快速傅里叶变换 学习之前先看懂这个 浅谈范德蒙德(Vandermonde)方阵的逆矩阵的求法以及快速傅里叶变换(FFT)中IDFT的原理--gzy hhh开个玩笑. 讲一下\(FFT\) ...

  6. 知识点简单总结——FWT(快速沃尔什变换),FST(快速子集变换)

    知识点简单总结--FWT(快速沃尔什变换),FST(快速子集变换) 闲话 博客园的markdown也太傻逼了吧. 快速沃尔什变换 位运算卷积 形如 $ f[ i ] = \sum\limits_{ j ...

  7. [学习笔记] $FWT$

    \(FWT\)--快速沃尔什变化学习笔记 知识点 \(FWT\)就是求两个多项式的位运算卷积.类比\(FFT\),\(FFT\)大多数求的卷积形式为\(c_n=\sum\limits_{i+j=n}a ...

  8. FWT快速沃尔什变换——基于朴素数学原理的卷积算法

    这是我的第一篇学习笔记,如有差错,请海涵... 目录 引子 卷积形式 算法流程 OR卷积 AND卷积 XOR卷积 模板 引子 首先,考虑这是兔子 数一数,会发现你有一只兔子,现在,我再给你一只兔子 再 ...

  9. 初学FWT(快速沃尔什变换) 一点心得

    FWT能解决什么 有的时候我们会遇到要求一类卷积,如下: Ci=∑j⊕k=iAj∗Bk\large C_i=\sum_{j⊕k=i}A_j*B_kCi​=j⊕k=i∑​Aj​∗Bk​此处乘号为普通乘法 ...

随机推荐

  1. day 7-5 守护线程

    一. 守护线程 无论是进程还是线程,都遵循:守护进程(线程)会等待主进程(线程)运行完毕后被销毁. 需要强调的是:运行完毕并非终止运行. 1.对主进程来说,运行完毕指的是主进程代码运行完毕. 2.对主 ...

  2. C# Note26: [MethodImpl(MethodImplOptions.Synchronized)]与lock机制

    在进行.NET开发时,经常会遇见如何保持线程同步的情况.在众多的线程同步的可选方式中,加锁无疑是最为常用的.如果仅仅是基于方法级别的线程同步,使用System.Runtime.CompilerServ ...

  3. 高并发之API接口限流

    在开发高并发系统时有三把利器用来保护系统:缓存.降级和限流 缓存 缓存的目的是提升系统访问速度和增大系统处理容量 降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再 ...

  4. git上传本地代码到github

      1.(先进入项目文件夹)通过命令 git init 把这个目录变成git可以管理的仓库 git init 2.把文件添加到版本库中,使用命令 git add .添加到暂存区里面去,不要忘记后面的小 ...

  5. java 从键盘录入的三种方法

    详细内容连接 https://blog.csdn.net/StriverLi/article/details/52984066

  6. rsync: chgrp "/.hosts.NBCxBB" (in test) failed: Operation not permitted (1)

    #记一次rsync出现的错误(网上基本都是说权限问题) #这并不是权限的问题,应为实际的文件已经传过去了,但是rsync就是会报这个错误,(虽然使用是正常的,但是看着就是不爽) [root@local ...

  7. Python给照片换底色(蓝底换红底)

    环境要求 Python3 numpy函数库 opencv库 安装 下载适应版本的numpy函数库,我电脑是WIN10 64位,安装的函数库是 numpy-1.13.1+mkl-cp36-cp36m-w ...

  8. SpringBoot之处理JSON数据举例

    SpringBoot使用@RequestBody注解会自动将请求body中的json数据绑定到参数上.使用@ResponseBody注解,在返回参数时自动将对象转换为JSON格式返回. 举例代码: c ...

  9. 在Linq to sql 和 Entity framework 中使用lambda表达式实现left join

    在Linq to sql 和 Entity framework 中使用lambda表达式实现left join 我们知道lambda表达式在Linq to sql 和 Entity framework ...

  10. bzoj2152-[国家集训队]聪聪可可

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)--遇到这种问题,一般情况下石头剪刀布就好 ...