前言
老师讲课没怎么听,补学。
讲解
用于处理形如于
d p [ x ] = d p [ y ] ∗ v a l [ z ] ( y ∣ z = x 且 y & z = 0 ) dp[x]=dp[y]*val[z]\ (y|z=x\ 且\ y\&z=0) dp[x]=dp[y]∗val[z] (y∣z=x 且 y&z=0)
的一类dp
朴素做法:枚举 x x x,枚举 x x x 的子集 y y y进行状态转移,时间复杂度为 O ( 3 l o g n ) O(3^{{logn}}) O(3logn)。
我们考虑对方法进行改进:我们发现,这个dp转移实际上就是一个有条件的卷积。我们改变状态,存储二进制位有多少个1为 t t t,将dp式转化为:
d p [ x ] [ t 3 ] = d p [ y ] [ t 2 ] ∗ v a l [ z ] [ t 1 ] ( y ∣ z = x 且 t 2 + t 1 = t 3 ) dp[x][t3]=dp[y][t2]*val[z][t1]\ (y|z=x\ 且\ t2+t1=t3) dp[x][t3]=dp[y][t2]∗val[z][t1] (y∣z=x 且 t2+t1=t3)
那么我们这样用 FWT 进行转移即可。
时间复杂度为 n ∗ 2 l o g n ∗ n n*2^{logn}*n n∗2logn∗n