集合幂级数瞎扯

集合幂级数瞎扯

给自己写的,欢迎指正。

位运算卷积,核心记住:\(c(0/1,x)c(0/1,y)=c(0/1,j\oplus k)\)

由于最后要求逆,所以设计的矩阵要可逆。

or 运算:

\[\begin{bmatrix} 1 & 0 \\ 1 & 1 \end{bmatrix} \ \ \ \ \ \ \ \begin{bmatrix} 1 & 1 \\ -1 & 1 \\ \end{bmatrix} \]

and 运算:

\[\begin{bmatrix} 1 & 1 \\ 0 & 1 \end{bmatrix} \ \ \ \ \ \ \ \begin{bmatrix} 1 & -1 \\ 0 & 1 \\ \end{bmatrix} \]

xor 运算:

\[\begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix} \ \ \ \ \ \ \ \begin{bmatrix} 0.5 & 0.5 \\ 0.5 & -0.5 \\ \end{bmatrix} \]

矩阵可能不止一种,理解方式也不止一种。

void FWT(ll* P,ll op=1)
{
	for(ll j=1;j<m;j<<=1)for(ll i=0,x=0,y=0;i<m;i++,i+=i&j)
		x=P[i],y=P[i+j],P[i]=(x+y)*op%H,P[i+j]=(x-y+H)*op%H;
}

书写的时候不需要写矩阵,这个代码是学 xyf 大蛇的,精炼。

子集卷积:

考虑把它改写成:\(x^Sy^{|S|}\) 那么没有交集就意味着 \(|A|+|B|=|A\cap B|\),那么对于不同的 \(y\) 分别做 FWT 然后再做多项式卷积。

FWT 大多时候只是最外层的壳子,通常在最开始的解壳最后的时候加壳,可恶的是加了壳子之后调试难度大大增加。

FWT 的位矩阵还是太超前了,考虑实际意义,or 的 FWT 相当于子集和,and 的 FWT 相当于超级和,那么可以很快的求出一个点对另一个点的贡献,or 和 and 的 IFWT 贡献系数是 \((-1)^{|S|-|T|}\)

xor 下,\(S\)\(T\) 的贡献是 \((-1)^{|S \& T|}\),所以在初始值很少或者值出现地位置有规律的时候是不需要做 FWT 的,IFWT 的贡献系数是 \(\frac{1}{2^n}(-1)^{|S \& T|}\)

UOJ310:一个异或和为 \(0\) 的集合的贡献为 \(2^{|S|}\),那么幂级数就是 \((1+2x^{a_i})\) 做异或卷积,暴力做法是对每个 \(i\) FWT,显然爆了,知道每一个点对其他点的贡献系数,那么一个点收到的贡献只能可能是 1 或者 -3,我们知道系数和以及个数和,就可以解出 1 和 -3 分别的个数,然后 IFWT 就好了。

CF1119H:上面只有两个位置有值,这里是 \(k\) 个,考虑通用解法,还是先算出所有的和的 FWT,然后考虑算出 \(2^{k}\) 每种的贡献次数,考虑算出 \(2^{k}\) 种异或和的和的 FWT 然后这个等于贡献次数的 FWT,证明,然后 IFWT 就可以算贡献次数了。

ABC367G:考虑类似上面求出贡献数组,但是多了一个 \(m\) 的倍数,考虑在另一维做暴力循环卷积即可。

QOJ5089:求的是每个点度数均为偶数的子图,\(\prod (1+x^{u_i,v_i}y)\) 做异或卷积,考虑算 \((1-y)\) 的贡献次数,即为边里恰好有一个点在集合 \(S\) 中,直接递推转移即可,最后只用算 \(x^0\),那么相当于就是所有的系数和,组合数暴力计算即可。

CF662C:考虑如果确定了行的翻转次数,列的贡献就是 \(\min(|S|,n-|S|)\),脑筋急转弯一下,那么 \(f\oplus g=h\)\(f\) 是每一列的原状态,\(g\) 是贡献,\(h\) 就是行的翻转情况。

子集卷积既可以刻画不交又可以刻画选中了全集,所以大多数时候可以网上套。

CF2070F :不一定是交集为空,可以根据实际意义改写 \(x^Sy^{|S\cap T|}\)

CF1034E:子集卷积复杂度暴了,至于很小,考虑设 \(y=4\),最后直接除以 \(4^{|y|}\)

CF1326F2:容斥,计算钦定某些位置为 \(1\) 的位置,那么把一看成边,会形成若干连通块,显然顺序不影响,那么就是 \(p(n)\) 个,考虑算出每个子集形成一条链的方案数,然后大力 FWT 之后枚举拆分数得出方案数,最后 IFWT 回去即可(只用求一项,算贡献即可)

与多项式操作(dp)结合,难度更为巨大。

P6570:即为 \(\prod (x^{\empty+x^{a_i}})\) 乘法是子集卷积,考虑 ln+exp 即可,可以暴力实现多项式操作:this

P6846:我的 DAG 容斥 /ll,考虑钦定入读为 \(0\) 的独立集 \(T\) 贡献为 \((-1)^{|T|-1}\) ,设集合幂级数 \(G\),贡献即为 \(\frac{1}{1-G}\),还是 FWT 之后求逆即可。

loj154:无敌了,考虑 FWT 之后求 \(exp_{\le k}\),还得套多项式快速幂,恶心。

AGC034F:一种很好的梳理方式为:

\((f_0,f_1,\cdots,f_{2^n-1})\oplus (p_0,p_1,\cdots ,p_{2^n-1})=(f_{0}+2^n-1,f_1-1,\cdots,f_{2^n-1})\)

\((f_0,f_1,\cdots,f_{2^n-1})\oplus (p_0-1,p_1,\cdots ,p_{2^n-1})=(2^N-1,-1,\cdots -1)\)

直接上 FWT 和求逆,但是第零项可能除到 \(0\) 很讨厌,一种做法是考虑把 \(f_0\) 设出来然后系数偏移一下,还有一种是依据 \(IFWT(f_0)=0\) 反推出 FWT 第 \(0\) 项的系数。

P5326:金典牢题,跟上面一样,只不过 \(p_S\) 只有在 \(2^i\) 有系数,考虑手动 FWT ,推出 \(FWT(F)\),(注意第 \(0\) 项),然后再手动 IFWT,最后大力 DP,这也太牛了。

CF1713F:考虑先推到对角线上再推到边上,两边都是超级/子集和,直接 IFWT/FWT 回去就好了。

ABC288G:考虑从 \(B\) 反推系数,大概还是类似 FWT 按位考虑贡献,设计矩阵,手动求逆即可。

\[\begin{bmatrix} 1 & 1 & 0\\ 1 & 1 & 1\\ 0 & 1 & 1 \end{bmatrix} \ \ \ \ \ \ \ \begin{bmatrix} 0 & 1 & -1\\ 1 & -1 & 1\\ -1 & 1 & 0 \end{bmatrix} \]

还有亿些 K 进制 FWT 题目,好像挺厉害的,下次再学把(会有下次吗)。

posted @ 2025-03-18 09:27  Hanghang007  阅读(83)  评论(3)    收藏  举报