除了 $K$ 进制不进位加法( $Xor$ ),其它两种笔者并不知道可不可做,所以底下的都是说的不进位加法
考虑 $2$ 进制 $ ext{FWT}$ ,是把左边(设为 $a$ )和右边 (设为 $b$ ),递归以后变成 $a'=a+b,b'=a-b$ ,再回到上面继续做
也就是每层左边第 $i$ 位和右边第 $i$ 位对这个矩阵进行线性变换:
egin{bmatrix} 1& 1\1& -1 end{bmatrix}
发现 $omega_2^1=-1$
就盲猜一波 $K$ 维线性变换矩阵就是 $a_{i,j}=omega_K^{i imes j}$ ( $0 le i,j < K$ )
事实上手推一下发现确实也是这样,证明笔者也不会(,所以某种意义上就是存个板子在这里,顺便看看到底咋实现
namespace FWT{ #define G 3 #define MAXK 11 int K,w[MAXK*MAXK]; unsigned long long tmp[MAXK]; inline void Xor(int N,int a[],int opt){ for(int i=1;i<N;i*=K) for(int p=i*K,j=0;j<N;j+=p) for(int k=0;k<i;k++){ int l=j+k; for(int p=0;p<K;p++){ int x=l+p*i; for(int q=0;q<K;q++) tmp[q]+=1ull*w[p*q]*a[x]; } for(int p=0;p<K;p++) a[l+i*p]=tmp[p]%mod,tmp[p]=0; } if(!opt)return; int invn=qpow(N,mod-2); for(int i=0;i<N;i++) a[i]=1ll*a[i]*invn%mod; } inline void init(int Kk){ K=Kk,w[0]=1; w[1]=qpow(G,(mod-1)/K); int lim=(K-1)*(K-1); for(int i=2;i<=lim;i++) w[i]=1ll*w[i-1]*w[1]%mod; } }