FWT学习笔记

FWT学习笔记


参考:

  1. 快速沃尔什变换(FWT)学习笔记
  2. FWT 详解 知识点

定义:

快速沃尔什变换(FWT)主要解决位运算卷积的问题。给定两个数组 \(A\)\(B\) (长度为2的整数幂):
\[C_k = \sum_{i \oplus j=k}A_i·B_i\] 其中\(\oplus\)可以是与,或,异或。FWT利用类似于FFT的想法,把 \(A\)\(B\) 分别正变换,在一个好的复杂度得到 \(A\)\(B\) 按位卷积的的正变换,最后再逆变换回来就是答案。

模版[Luogu4717]

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
typedef long long ll;
const int mod = 998244353;
const int inv2 = 499122177;
const int N = (1<<17);
inline int read() {char c=getchar(); int x=0,f=1;while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;
}
inline void write(int x) {if(x>=10)write(x/10);putchar('0'+x%10);
}
using namespace std;
inline int add(int x,int y) {x+=y;if(x>=mod)x-=mod;return x;
}
inline int sub(int x,int y) {x-=y;if(x<0)x+=mod;return x;
}
void FWT_or(int a[],int n,int on) {for(int i=1;i<n;i<<=1) {for(int j=0;j<n;j+=(i<<1)) {for(int k=0;k<i;++k) {int u=a[j+k], t=a[j+k+i];a[j+k]=u;if(on==1)a[j+k+i]=add(t,u);else a[j+k+i]=sub(t,u);}}}
}
void FWT_and(int a[],int n,int on) {for(int i=1;i<n;i<<=1) {for(int j=0;j<n;j+=(i<<1)) {for(int k=0;k<i;++k) {int u = a[j+k], t=a[j+k+i];if(on==1) a[j+k]=add(u,t);else a[j+k]=sub(u,t);a[j+k+i]=t;}}}
}
void FWT_xor(int a[],int n,int on) {for(int i=1;i<n;i<<=1) {for(int j=0;j<n;j+=(i<<1)) {for(int k=0;k<i;++k) {int u=a[j+k], t=a[j+k+i];a[j+k]=add(u,t); a[j+k+i]=sub(u,t);if(on==-1) {a[j+k]=(ll)a[j+k]*inv2%mod;a[j+k+i]=(ll)a[j+k+i]*inv2%mod;}}}}
}
int a[N],b[N],c[N],d[N];
int main() {int n = read(), m = (1<<n);rep(i,0,m-1) a[i]=read();rep(i,0,m-1) b[i]=read();memcpy(c,a,sizeof(c));memcpy(d,b,sizeof(b));FWT_or(c,m,1); FWT_or(d,m,1);rep(i,0,m-1) c[i]=(ll)c[i]*d[i]%mod;FWT_or(c,m,-1);rep(i,0,m-1)write(c[i]),putchar(' ');putchar('\n');memcpy(c,a,sizeof(c));memcpy(d,b,sizeof(b));FWT_and(c,m,1); FWT_and(d,m,1);rep(i,0,m-1) c[i]=(ll)c[i]*d[i]%mod;FWT_and(c,m,-1);rep(i,0,m-1)write(c[i]),putchar(' ');putchar('\n');memcpy(c,a,sizeof(c));memcpy(d,b,sizeof(b));FWT_xor(c,m,1); FWT_xor(d,m,1);rep(i,0,m-1) c[i]=(ll)c[i]*d[i]%mod;FWT_xor(c,m,-1);rep(i,0,m-1)write(c[i]),putchar(' ');putchar('\n');return 0;
}

BZOJ4589[Hard Nim]

题意:求长度为n,元素为小于m的质数,且异或和为0的方案数

做法:设 \(f[i][j]\) 表示长度为i的序列异或和为j的方案数,则\(f[i][x \oplus y] = f[i-1][x]·f[1][y]\)\(f[1]\)内编号为素数的位置为1,其余为0,那么\(f[i][k] = \sum _{x \oplus y=k} f[i-1][x]·f[1][y]\),答案就是要求 \(f[1]\) 卷积 \(n\) 次的f[n][0],又因为每次乘的都是 \(f[1]\) 所以可以先对 \(f[1]\) 求FWT正变换,分别n次幂后再加起来,最后逆变换出答案向量 \(f[n]\)

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define pb push_back
typedef long long ll;
const int N = 65537<<1;
const ll mod = 1e9 + 7;
using namespace std;
int m, p[N], notp[N];
ll n,a[N],inv2;
ll q_pow(ll a,ll b) {ll ans = 1;while(b) {if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;
}
inline ll add(ll x,ll y) {x+=y;if(x>=mod)x-=mod;return x;
}
inline ll sub(ll x,ll y) {x-=y;if(x<0)x+=mod;return x;
}
void FWT_xor(ll a[],int n,int on) {for(int i=1;i<n;i<<=1) {for(int j=0;j<n;j+=(i<<1)) {for(int k=0;k<i;++k) {ll u = a[j+k], t = a[j+k+i];a[j+k]=add(u,t); a[j+k+i]=sub(u,t);if(on==-1) {a[j+k]=a[j+k]*inv2%mod;a[j+k+i]=a[j+k+i]*inv2%mod;}}}}
}
void init() {inv2 = q_pow(2,mod-2);notp[1] = 1;for(int i=2;i<=5e4;++i) {if(!notp[i])p[++p[0]]=i;for(int j=1;j<=p[0]&&p[j]*i<=5e4;++j) {notp[p[j]*i] = 1;if(i%p[j]==0)break;}}
}
int main() {init();while(~scanf("%lld%d",&n,&m)) {memset(a,0,sizeof(a));rep(i,1,m) a[i] = (!notp[i]);int len;for(len=1;len<=m;len<<=1);FWT_xor(a,len,1);rep(i,0,len-1) a[i]=q_pow(a[i],n);FWT_xor(a,len,-1);printf("%lld\n",a[0]%mod);}return 0;
}

转载于:https://www.cnblogs.com/RRRR-wys/p/9478045.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/320619.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hdu5709-Claris Loves Painting【线段树合并】

正题 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid5709 题目大意 nnn个点的一棵树&#xff0c;每次有询问(u,k)(u,k)(u,k)表在uuu的子树中&#xff0c;距离uuu不超过kkk的节点中有多少不同颜色的节点。 解题思路 线段树维护每个深度有多少是颜色出现的最浅的位置&am…

【DP】【高精】WZK打雪仗(jzoj 1997)

WZK打雪仗 jzoj 1997 题目大意&#xff1a; 在一个环上有n*2个点&#xff0c;问有多少种连法可以用n条线连接成n对点 输入样例 5输出样例 42解释&#xff1a; 一种可行的方案如下&#xff1a; 数据范围 对于30%数据&#xff1a; n<30。 对于100%数据&#xff1a; …

月旦评 之 DevOps招贤令2018

公元164-182年间&#xff0c;汝南平舆的许氏兄弟于每月初一品评人物&#xff0c;褒贬时政&#xff0c;被称为“月旦评”。所谓“子治世之能臣&#xff0c;乱世之奸雄也”这句许邵评价曹操的话也是来自于“月旦评”&#xff1b;时间一下子来到了2018年&#xff0c;LEANSOFT DevO…

牛客网暑期ACM多校训练营(第九场)

牛客网暑期ACM多校训练营&#xff08;第九场&#xff09; A. Circulant Matrix 做法&#xff1a;看到下标 \(xor\) 这种情况就想 \(FWT\)&#xff0c;可是半天没思路&#xff0c;于是放弃了。。其实这个 \(n\) 疯狂暗示啊。设未知数向量为 \(x\)&#xff0c;列一下方程组就可以…

函数式编程之-模式匹配(Pattern matching)

编者&#xff1a;C# 7.0也加入了模式匹配&#xff0c;来源于F#。模式匹配在F#是非常普遍的&#xff0c;用来对某个值进行分支匹配或流程控制。模式匹配的基本用法模式匹配通过match...with表达式来完成&#xff0c;一个完整的模式表达式长下面的样子&#xff1a;match [somethi…

P4123-[CQOI2016]不同的最小割【网络流,分治】

正题 题目大意:https://www.luogu.com.cn/problem/P4123 题目大意 一张无向图&#xff0c;求所有点对之间有多少不同的最小割。 解题思路 考虑分治的做法&#xff0c;如果我们得知了(s,t)(s,t)(s,t)的最小割www&#xff0c;并且剩下的残量网络中连通点集SSS与sss连通&#x…

【DP】饥饿的WZK(jzoj 1998)

饥饿的WZK jzoj 1988 题目大意&#xff1a; 有很多个点&#xff0c;并且给出n个区间&#xff0c;问在选的区间不重复的前提下&#xff0c;选的区间的点数总和最大是多少 输入样例 3 1 3 7 8 3 4输出样例 5数据范围 对于100%的数据&#xff1a;1<N<2000&#xff0c…

ACM-ICPC 2018 徐州赛区网络预赛 D. EasyMath

ACM-ICPC 2018 徐州赛区网络预赛 D. EasyMath 做法&#xff1a;\[f(m,n) \sum _{i1}^{m} \mu(in) \sum_{i1}^{m}[gcd(i,n)1]\mu(i)\mu(n) \mu(n)\sum_{d|n}\mu(d)f(\frac{m}{d},d)\] 边界: n1&#xff0c;杜教筛求\(\sum_{i1}^{m}\mu(i)\)&#xff0c;m 1, 返回\(\mu(n)\)&…

51nod1601-完全图的最小生成树计数【Trie,分治】

正题 题目链接:http://www.51nod.com/Challenge/Problem.html#problemId1601 题目大意 nnn个点的完全图&#xff0c;边(i,j)(i,j)(i,j)的权值为aixoraja_i\ xor\ a_jai​ xor aj​。求最小生成树和方案数。 解题思路 对于一个高位数&#xff0c;将这一位为000和这一位为111分…

纪中C组模拟赛总结(2019.7.8)

成绩&#xff1a; 注&#xff1a; rankrankrank是有算其它dalaodalaodalao的 hkydalaohkydalaohkydalao竟不屑于交代码 rankrankranknamenamenamescorescorescoreT1T1T1T2T2T2T3T3T3T4T4T4171717wjjwjjwjj185185185100100100858585000000212121lyflyflyf170170170100100100707…

HDU5442

HDU5442 做法&#xff1a;把原串复制一份加在后边&#xff0c;中间插特殊入个特殊字符&#xff0c;再把翻转后的串加在后边&#xff0c;同样复制一份。然后做后缀数组&#xff0c;按题意处理细节即可。 #include <cstdio> #include <iostream> #include <algori…

Asp.Net Core SignalR 与微信小程序交互笔记

什么是Asp.Net Core SignalRAsp.Net Core SignalR 是微软开发的一套基于Asp.Net Core的与Web进行实时交互的类库&#xff0c;它使我们的应用能够实时的把数据推送给Web客户端。功能自动管理连接允许同时广播到所有客户端也可以广播到指定的组或者特定的客户端在Github上开源&am…

手机(jzoj 1983)

手机 jzoj 1983 题目大意&#xff1a; 在手机输入键盘上有很多键&#xff08;如下图&#xff09;&#xff0c;每一个位置按一次就是第一个字母&#xff0c;第二次就是第二个字母&#xff08;空格按0一次&#xff09;&#xff0c;现在问打出一条信息最少按几下&#xff1f; …

P2371-[国家集训队]墨墨的等式【同余最短路】

正题 题目链接:https://www.luogu.com.cn/problem/P2371 题目大意 nnn个aia_iai​&#xff0c;求有多少个b∈[l,r]b\in[l,r]b∈[l,r]满足∑i1naixib\sum_{i1}^na_ix_ib∑i1n​ai​xi​b有正整数解。 解题思路 因为有一个a1a_1a1​在&#xff0c;而且x1x_1x1​可以是任意正整数…

HDU5514 Frogs

HDU5514 Frogs 题意&#xff1a;将\([0,m)\)所有符合\(a[i]*t ~mod~ m\)的值求和 做法&#xff1a; \(a[i]*t ~mod~ m\) 会在 \(gcd(a[i],m)\) 的倍数出现&#xff0c;因此问题等价与求&#xff1a;\[ \sum_{i1}^{m-1} [ [(a[1],m)|i] or [(a[2],m)|i] or ... or [(a[n],m)|i] …

HDU5573

HDU5573 做法&#xff1a;本题的关键在于题目限制了n≤2^k&#xff0c;如果可以不选的话&#xff0c;我就会用最左边的1&#xff0c;2&#xff0c;4...凑出n&#xff0c;这里需要用减法&#xff0c;于是先把所有的数都加到答案里&#xff0c;这个值与n的插值&#xff0c;就是我…

【结论】游戏(jzoj 1984)

游戏 jzoj 1984 题目大意&#xff1a; 有很多个点&#xff0c;两个人每次可以取走2k2^k2k&#xff08;k是一个自然数&#xff0c;可以自己选&#xff09;个点&#xff0c;取走最后一个点的人胜利&#xff0c;现在你先选&#xff0c;问你是否能赢&#xff08;能赢输出MaoLaoD…

Go vs .NET Core 2.1

.NET Core 2.1 正式发布之际&#xff0c;微软团队在博客的中提到了 .NET Core 2.1 中的性能提升。这让我想起了去年 Go 语言 Iris MVC 框架作者做的 Go 与 .NET Core 2.0 之间的性能对比(具体可看https://hackernoon.com/go-vs-net-core-in-terms-of-http-performance-7535a61b…

CF786E-ALT【网络流,倍增】

正题 题目链接:https://www.luogu.com.cn/problem/CF786E 题目大意 nnn个点的一棵树&#xff0c;mmm个人每个人走一个路径。 给一些人狗或者一些边狗每个人要求要么它自己有狗要么它走的路径上都有狗。 解题思路 考虑最小割&#xff0c;其实就是要么割一个人要么割一整条路径…

HDU6038 - Function

HDU6038 - Function 做法&#xff1a; 展开后有&#xff0c;\(f(i) b_{f(a_i)} b_{b_{f(a_{a_i})}} ... b_{b_{..b_{f(i)}}}\)&#xff0c;可以发现当 \(a_i\) 所在的循环节中确定一个时&#xff0c;整个循环都确定了&#xff0c;根据这个式子还可以发现&#xff0c;对于一…