CF1119H-Triple【FWT】
正題
題目鏈接:https://www.luogu.com.cn/problem/CF1119H
題目大意
nnn個可重集,第iii個里有xxx個aia_iai?,yyy個bib_ibi?,zzz個cic_ici?。
對于每個t∈[0,2k)t\in[0,2^k)t∈[0,2k)求每個集合里取出一個數使它們異或起來等于ttt的方案數。
解題思路
如果直接nnn個東西FWTFWTFWT起來肯定過不了,我們需要根據每個集合里只有三種數這個性質來優化。
因為是xorxorxor卷積,所以第iii個位置FWTFWTFWT之后對jjj造成的影響是(?1)cnt(i&j)(-1)^{cnt(i\&j)}(?1)cnt(i&j)(其中cnt(x)cnt(x)cnt(x)表示xxx在二進制下111的個數)
那么就有
FWT(Si)=∑i=12k?1(?1)cnt(j&ai)x+(?1)cnt(j&bi)y+(?1)cnt(j&bi)zFWT(S_i)=\sum_{i=1}^{2^k-1}(-1)^{cnt(j\&a_i)}x+(-1)^{cnt(j\& b_i)}y+(-1)^{cnt(j\&b_i)}zFWT(Si?)=i=1∑2k?1?(?1)cnt(j&ai?)x+(?1)cnt(j&bi?)y+(?1)cnt(j&bi?)z
現在我們就可以單獨考慮每個x,y,zx,y,zx,y,z的貢獻了,然后每個FWT(Si)[j]FWT(S_i)[j]FWT(Si?)[j]有888個狀態,為了方便我們縮減一下狀態先。
首先我們先讓所有的xxx都取到,也就是讓所有的bi=bixorai,ci=cixoraib_i=b_i\ xor\ a_i,c_i=c_i\ xor\ a_ibi?=bi??xor?ai?,ci?=ci??xor?ai?,然后詢問答案的時候我們再異或上一個aaa的異或和即可。
現在每個FWT(Si)[j]FWT(S_i)[j]FWT(Si?)[j]有444種狀態,分別是(x+y+z),(x+y?z),(x?y+z),(x?y?z)(x+y+z),(x+y-z),(x-y+z),(x-y-z)(x+y+z),(x+y?z),(x?y+z),(x?y?z)。定義這些狀態數量分別為a1,a2,a3,a4a_1,a_2,a_3,a_4a1?,a2?,a3?,a4?
我們先考慮集合iii的每種狀態中yyy的影響FiF_iFi?,有Fi[k]=cnt(k&ai)F_i[k]=cnt(k\& a_i)Fi?[k]=cnt(k&ai?),而所有集合的影響和就是∑i=1nFi\sum_{i=1}^nF_i∑i=1n?Fi?。設Gi=IFWT(Fi)G_i=IFWT(F_i)Gi?=IFWT(Fi?)那么顯然有Gi[bi]=1G_i[b_i]=1Gi?[bi?]=1其他都為000。
然后影響和就是∑i=1nFWT(Gi)=FWT(∑i=1nGi)\sum_{i=1}^nFWT(G_i)=FWT(\sum_{i=1}^nG_i)i=1∑n?FWT(Gi?)=FWT(i=1∑n?Gi?)
所以直接把GGG都加起來然后FWTFWTFWT就好了,定義yyy的影響為c1c_1c1?。
然后再同理搞出zzz和y+zy+zy+z的影響,分別為c2,c3c_2,c_3c2?,c3?,那么就有方程組
{a1+a2+a3+a4=na1+a2?a3?a4=c1a1?a2+a3?a4=c2a1?a2?a3+a4=c3\left\{\begin{matrix} a_1+a_2+a_3+a_4=n\\ a_1+a_2-a_3-a_4=c_1\\ a_1-a_2+a_3-a_4=c_2\\ a_1-a_2-a_3+a_4=c_3 \end{matrix}\right.????????a1?+a2?+a3?+a4?=na1?+a2??a3??a4?=c1?a1??a2?+a3??a4?=c2?a1??a2??a3?+a4?=c3??
解出來就好了,然后用快速冪算出來F=∏i=1nFWT(Si)F=\prod_{i=1}^nFWT(S_i)F=∏i=1n?FWT(Si?),求一遍IFWT(F)IFWT(F)IFWT(F)即可。
時間復雜度O(2kk+nlog?(x+y+z))O(\ 2^kk+n\log(x+y+z)\ )O(?2kk+nlog(x+y+z)?)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=2e5+10,P=998244353; const ll inv2=(P+1)/2; ll n,k,x,y,z,xs; ll f1[N],f2[N],f3[N],f[N]; ll power(ll x,ll b){ll ans=1;x%=P;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans; } void FWT(ll *f,ll n,ll op){for(ll p=2;p<=n;p<<=1)for(ll k=0,len=p>>1;k<n;k+=p)for(ll i=k;i<k+len;i++){ll x=f[i],y=f[i+len];if(op==1){f[i]=x+y;f[i+len]=x-y;}else{f[i]=(x+y)*inv2%P;f[i+len]=(x-y)*inv2%P;}}return; } signed main() {scanf("%lld%lld",&n,&k);k=1<<k;scanf("%lld%lld%lld",&x,&y,&z);for(ll i=1;i<=n;i++){ll a,b,c;scanf("%lld%lld%lld",&a,&b,&c);xs^=a;b^=a;c^=a;f1[b]++;f2[c]++;f3[b^c]++;}FWT(f1,k,1);FWT(f2,k,1);FWT(f3,k,1);for(ll i=0;i<k;i++){ll c1=f1[i],c2=f2[i],c3=f3[i];ll a1,a2,a3,a4;a4=(c3-c1-c2+n)/4;a3=-(c1-n+2ll*a4)/2;a2=-(c2-n+2ll*a4)/2;a1=n-a2-a3-a4;f[i]=power(x+y+z,a1)%P*power(x+y-z,a2)%P;f[i]=f[i]*power(x-y+z,a3)%P*power(x-y-z,a4)%P;}FWT(f,k,-1);for(ll i=0;i<k;i++)printf("%lld ",(f[i^xs]+P)%P);return 0; }總結
以上是生活随笔為你收集整理的CF1119H-Triple【FWT】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 律师备案查询(和律师备案)
- 下一篇: 慰藉的读音 慰藉解释