[atAGC034F]RNG and XOR

令$N=2^{n}$先将$\forall 0\le i<N,a_{i}$除以$\sum_{i=0}^{N-1}a_{i}$,即变为概率

令$f_{i}$表示$i$的答案(第一次变成$i$的期望步数),则
$$
\begin{cases}f_{0}=0\\f_{i}=\left(\sum_{j=0}^{N-1}a_{j}f_{i\oplus j}\right)+1&(1\le i<N)\end{cases}
$$
定义$\bigoplus$为异或卷积,令$A(x)$和$F(x)$分别为对应序列的生成函数,则
$$
A\bigoplus F=\sum_{i=0}^{N-1}\left(\sum_{j=0}^{N-1}a_{j}f_{i\oplus j}\right)x^{i}=F-\sum_{i=1}^{N-1}x^{i}+\sum_{i=0}^{N-1}a_{i}f_{i}
$$
另一方面,注意到$\sum_{i=0}^{N-1}a_{i}=\sum_{i=0}^{N-1}f_{i}=1$(显然概率和为1),那么
$$
\sum_{i=0}^{N-1}[x^{i}](A\bigoplus F)=\sum_{j=0}^{N-1}a_{j}\sum_{i=0}^{N-1}f_{i\oplus j}=1
$$
而$F-\sum_{i=1}^{N-1}x^{i}+\sum_{i=0}^{N-1}a_{i}f_{i}$与左式相同,系数和也为1,即有
$$
\sum_{i=0}^{N-1}f_{i}-(N-1)+\sum_{i=0}^{N-1}a_{i}f_{i}=1
$$
不难解得$\sum_{i=0}^{N-1}a_{i}f_{i}=N-1$,代回原式即$A\bigoplus F=F-\sum_{i=1}^{N-1}x^{i}+(N-1)$

构造$A'=A-1$(即将$a_{0}$减1后的生成函数),则
$$
A'\bigoplus F=A\bigoplus F-\sum_{i=0}^{N-1}f_{i}x^{i}=(N-1)-\sum_{i=1}^{N-1}x^{i}
$$
直接FWT即可,以下过程即FWT的推导,熟练FWT的可以跳至这里——

定义$FWT(A)_{i}=\sum_{j=0}^{N-1}(-1)^{cnt(i\and j)}A_{j}$(即通常FWT后的序列),则有
$$
FWT(A\bigoplus F)_{i}=\sum_{j=0}^{N-1}(-1)^{cnt(i\and j)}\sum_{k=0}^{N-1}A_{k-1}F_{j\oplus k}
$$
(其中$cnt(x)$表示$x$二进制下1的个数)

注意到$cnt(i\and j)\equiv cnt(i\and k)+cnt(i\and (j\oplus k))(mod\ 2)$,代入即
$$
FWT(A\bigoplus F)_{i}=\left(\sum_{k=0}^{N-1}(-1)^{cnt(i\and k)}A_{k}\right)\left(\sum_{j=0}^{N-1}(-1)^{cnt(i\and (j\oplus k))}F_{j\oplus k}\right)=FWT(A)_{i}FWT(F)_{i}
$$
反过来,当求出$FWT(A)_{i}$和$FWT(A\bigoplus F)_{i}$时,也有$FWT(F)_{i}=\frac{FWT(A\bigoplus F)_{i}}{FWT(A)_{i}}$

得到$FWT(F)_{i}$后,考虑$FWT(FWT(F))_{i}$,即
$$
FWT(FWT(F))_{i}=\sum_{j=0}^{N-1}(-1)^{cnt(i\and j)}\sum_{k=0}^{N-1}(-1)^{cnt(j\and k)}F_{k}=\sum_{k=0}^{N-1}F_{k}\sum_{j=0}^{N-1}(-1)^{cnt(j\and (i\oplus k))}
$$
考虑后者,对$i\oplus k$是否为0分类讨论:

1.当$i\oplus k$为0,也即$i=k$,不难得到此时的式子为$NF_{i}$

2.当$i\oplus k$不为0时,假设其二进制下第$x$位为1,则$j$和$j\oplus 2^{x}$时的值即相互抵消,结果为0

综上,即可得$F_{i}=\frac{FWT(FWT(F))_{i}}{N}$,即可从$FWT(F_{i})$得到$F_{i}$(即IFWT)

上述过程看似没有问题,但当$FWT(A)_{i}=0$时,无法确定$FWT(F)_{i}$

注意到此时必然有$FWT(A\bigoplus F)_{i}=0$,而$A\bigoplus F=(N-1)-\sum_{i=1}^{N-1}x^{i}$,直接代入式子,即
$$
FWT(A\bigoplus F)_{i}=\sum_{j=0}^{N-1}(-1)^{cnt(i\and j)}(A\bigoplus F)_{j}=(N-1)-\sum_{j=1}^{N-1}(-1)^{cnt(i\and j)}
$$
不难发现当$i\ne 0$时,$cnt(i\and j)$不可能全为偶数,因此结果不为0,同时$i=0$时结果为0

由此,$FWT(A)_{i}=0$的位置也仅有$i=0$,不妨先将其设置为0,也可以得到一个$F'$,此时$[x^{0}]F'$与0的差值即是$-\frac{FWT(F)_{0}}{N}$,并以此修正(或再做一次)即可

总复杂度为$o(nN)$,可以通过

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define M (1<<18)
 4 #define mod 998244353
 5 #define ll long long
 6 int N,n,s,a[M],b[M],f[M];
 7 int qpow(int n,int m){
 8     int s=n,ans=1;
 9     while (m){
10         if (m&1)ans=(ll)ans*s%mod;
11         s=(ll)s*s%mod;
12         m>>=1;
13     }
14     return ans;
15 }
16 void fwt(int *a,int p){
17     for(int i=0;i<n;i++)
18         for(int j=0;j<N;j++)
19             if (j&(1<<i)){
20                 int x=a[j^(1<<i)],y=a[j];
21                 a[j^(1<<i)]=(x+y)%mod;
22                 a[j]=(x+mod-y)%mod;
23             }
24     if (p){
25         int s=qpow(N,mod-2);
26         for(int i=0;i<N;i++)a[i]=(ll)a[i]*s%mod;
27     }
28 }
29 int main(){
30     scanf("%d",&n);
31     N=(1<<n);
32     for(int i=0;i<N;i++){
33         scanf("%d",&a[i]);
34         s+=a[i];
35     }
36     s=qpow(s,mod-2);
37     for(int i=0;i<N;i++)a[i]=(ll)a[i]*s%mod;
38     a[0]=(a[0]+mod-1)%mod;
39     b[0]=N-1;
40     for(int i=1;i<N;i++)b[i]=mod-1;
41     fwt(a,0);
42     fwt(b,0);
43     for(int i=0;i<N;i++)b[i]=(ll)b[i]*qpow(a[i],mod-2)%mod;
44     memcpy(f,b,sizeof(f));
45     fwt(b,1);
46     f[0]=mod-(ll)N*b[0]%mod;
47     fwt(f,1);
48     for(int i=0;i<N;i++)printf("%d\n",f[i]);
49 }
View Code

 

posted @ 2021-07-19 14:46  PYWBKTDA  阅读(61)  评论(0编辑  收藏  举报