快速莫比乌斯/沃尔什变换 (FMT/FWT)
一、快速莫比乌斯变换
快速莫比乌斯变换简称
我们定义
1、或卷积
我们要求:
若有
定义:
所以利用子集和可以加速求出或卷积。
那如何快速求出子集和捏?不就是高维前缀和了捏!
高维前缀和:
code:
void FMT(int *f,int n,int op)//op=1为正变换,op=-1为逆变换
{
for(int i=0;i<n;++i)
for(int j=0;j<(1<<n);++j)
if(j&(1<<i))f[j]+=f[j^(1<<i)]*op;
}
2、与卷积
我们要求:
若有
定义:
这不就是高维后缀和了捏!
高维后缀和:
code:
void FMT(int *f,int n,int op)//op=1为正变换,op=-1为逆变换
{
for(int i=0;i<n;++i)
for(int j=0;j<(1<<n);++j)
if(j&(1<<i))f[j^(1<<i)]+=f[j]*op;
}
二、快速沃尔什变换
快速沃尔什变换简称
我们定义
1、异或卷积
定义:
和高维前缀和相似,我们对每一位依次考虑。对于第
code:
void FWT(int *f,int n,int op)
{
for(int i=1;i<(1<<n);i<<=1)
for(int j=0;j<(1<<n);j+=(i<<1))
for(int k=j;k<j+i;++k)
{
int x=f[k],y=f[k+i];
if(op==1)f[k]=x+y,f[k+i]=x-y;
else f[k]=(x+y)/2,f[k+i]=(x-y)/2;
}
}
是不是很简单
当然,
2、子集卷积
upt:2022.7.7
其实半年前就学了这东西,但忘了补到博客上来了(
期望构造一个占位函数
令
计算
代码:
#include<bits/stdc++.h>
#define pc(x) putchar(x)
#define ll long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){f=ch=='-'?-1:f;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
void write(int x)
{
if(x<0){x=-x;putchar('-');}
if(x>9)write(x/10);
putchar(x%10+48);
}
const ll mod=1e9+9;
int n;
int a[21][3000005],b[21][3000005],c[21][3000005];
int cnt(int x){return __builtin_popcount(x);}
void FMT(int *f,int n,int op)
{
for(int i=0;i<n;++i)
for(int j=0;j<(1<<n);++j)
if(j&(1<<i))f[j]+=f[j^(1<<i)]*op,f[j]=((ll)f[j]+mod)%mod;
}
int main()
{
n=read();
for(int i=0;i<(1<<n);++i)
a[cnt(i)][i]=read();
for(int i=0;i<(1<<n);++i)
b[cnt(i)][i]=read();
for(int i=0;i<=n;++i)FMT(a[i],n,1),FMT(b[i],n,1);
for(int i=0;i<=n;++i)
for(int j=0;j<=i;++j)
for(int k=0;k<(1<<n);++k)
c[i][k]=(ll)(c[i][k]+(ll)a[j][k]*b[i-j][k]%mod)%mod;
for(int i=0;i<=n;++i)FMT(c[i],n,-1);
for(int i=0;i<(1<<n);++i)write(c[cnt(i)][i]),pc(' ');
return 0;
}
代码是我自己打的,算法过程是搬APIO2022蔡欣然巨佬讲课的PDF。
3、子集卷积 exp
咕咕咕
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话