[ABC367G] Sum of (XOR^K or 0)

WrongAnswer_90發表於2024-08-27

My Blogs

[ABC367G] Sum of (XOR^K or 0)

考慮求出 \(ans_i\) 表示選了 \(m\) 的倍數個數,異或和是 \(i\) 的方案數再統計答案。

先考慮 \(m=1\) 怎麼做。相當於是 \(ans_i=[x^i]\prod_j (x^0+x^{a_j})\),這裡的乘法是異或卷積。如果直接 xor-FWT 複雜度不如暴力。令 \(F_i(x)\) 表示第 \(i\) 個數對應的集合冪級數,列出式子:

\[\begin{aligned} f_k&=[x^k]\text{FWT}(\prod_i F_i(x))\\ &=\prod_i ((-1)^{\text{popcount}(k\And a_i)}+(-1)^{\text{popcount}(k\And 0)})\\ &=\prod_i ((-1)^{\text{popcount}(k\And a_i)}+1)\\ \end{aligned} \]

所以只需要對於每個 \(k\) 求出求出 \(\text{popcount}(k\And a_i)\) 是奇數和偶數的 \(j\) 的個數。考慮構造一個新的集合冪級數 \(G_i(x)\),滿足 \(G_i(x)=x^{a_i}\),所以 \(\text{FWT}(G_i(x))=\sum_j x^j(-1)^{\text{popcount}(j\And a_i)}\)

\[g_k=\sum_{i}(-1)^{\text{popcount}(k\And a_i)}=\sum_i [x^k]\text{FWT}(G_i(x)) \]

因為 FWT 是線性變換,所以

\[g_k=[x^k]\text{FWT}(\sum_i G_i(x)) \]

\(x\) 表示 \(\text{popcount}(k\And a_i)\) 是偶數的個數,\(y\) 表示奇數,則有

\[\left\{\begin{matrix} x+y=n\\ x-y=g_k \end{matrix}\right. \]

可以對於每個 \(k\) 解出來 \(x,y\)。這樣就求出來了異或卷積的 FWT 陣列 \(f_i\),把 \(f\) IFWT 回去就得到了 \(ans_i\)

對於如何擴充到 \(m\not=1\),其實也很簡單,看成在 \(x\) 中選若干個,\(y\) 中選若干個,要求選的總數是 \(m\) 的倍數並且在 \(y\) 中每選一個都要乘一個 \(-1\)。預處理 \(a_{i,j}=\sum_{k\equiv j\pmod m}\binom{i}{k}\)\(b_{i,j}=\sum_{k\equiv j\pmod m}\binom{i}{k}(-1)^k\),然後把 \(a,b\) 合併起來就能求出 \(c_i\) 表示有 \(i\)\(1\)\(n-i\)\(-1\),在之中選 \(m\) 的倍數個的所有方案的權值乘積和,然後令 \(f_i=c_x\) 即可。總複雜度 \(\mathcal O(nm+k2^k)\),其中 \(k=20\)

const int N=1<<20;
int n,m,K,f[N],F[200010][110],G[200010][110],H[200010];
inline void mian()
{
	read(n,m,K),F[0][0]=G[0][0]=1;int x,y,iv=power(N,MOD-2),ans=0;
	for(int i=0;i<n;++i)for(int j=0;j<m;++j)
	Madd(F[i+1][j],F[i][j]),Madd(F[i+1][(j+1)%m],F[i][j]),
	Madd(G[i+1][j],G[i][j]),Mdel(G[i+1][(j+1)%m],G[i][j]);
	for(int i=0;i<=n;++i)for(int j=0;j<m;++j)
	Madd(H[i],Cmul(F[i][j],G[n-i][(m-j)%m]));
	for(int i=1;i<=n;++i)read(x),++f[x];
	for(int i=1;i<N;i<<=1)for(int j=0;j<N;j+=i<<1)for(int k=j;k<j+i;++k)
	x=f[k]+f[k+i],y=f[k]-f[k+i],f[k]=x,f[k+i]=y;
	for(int i=0;i<N;++i)f[i]=H[(n+f[i])>>1];
	for(int i=1;i<N;i<<=1)for(int j=0;j<N;j+=i<<1)for(int k=j;k<j+i;++k)
	x=Cadd(f[k],f[k+i]),y=Cdel(f[k],f[k+i]),f[k]=x,f[k+i]=y;
	for(int i=0;i<N;++i)Madd(ans,Cmul(f[i],iv,power(i,K)));
	write(ans);
}

相關文章