CF848E-Days of Floral Colours【dp,分治NTT】
正題
題目鏈接:https://www.luogu.com.cn/problem/CF848E
題目大意
2n2n2n個花排成一個圓環,nnn種顏色每種兩個,要求兩個相同顏色之間最小距離為1,21,21,2或nnn。
對于一種染色方案的權值為:刪除掉距離為nnn的顏色后,剩下的連續段長度的乘積。
求所有方案的染色之和對998244353998244353998244353取模。
1≤n≤500001\leq n\leq 500001≤n≤50000
解題思路
環好像很麻煩,先考慮線段上的,現在有兩個長度為nnn的數列,然后距離為nnn的點之間對應。染色可以看為連接兩個點。
然后設gig_igi?表示不使用跨越數列的連線,涂iii個的方案數,那么有gi=gi?2+gi?4g_i=g_{i-2}+g_{i-4}gi?=gi?2?+gi?4?(相鄰的連接/兩個都是隔著對方連)。
然后考慮有跨越數列的線的方案,且沒有其他連線跨過這條線,f0if0_if0i?表示第iii個是滿足條件的線的權值和。f1if1_if1i?則表示剛好有一對距離為222的點對跨越這個線的權值和。
那么有轉移方程
f0i=gii2+∑j=0i?1gjj2f0i?j?1+∑j=0i?3gj(j+1)2f1i?j?3f0_i=g_ii^2+\sum_{j=0}^{i-1}g_jj^2f0_{i-j-1}+\sum_{j=0}^{i-3}g_j(j+1)^2f1_{i-j-3}f0i?=gi?i2+j=0∑i?1?gj?j2f0i?j?1?+j=0∑i?3?gj?(j+1)2f1i?j?3?
(第一個是全程沒有其他橫跨邊,第二個是上一條橫跨邊兩邊沒有同色,第三個是上一條橫跨邊兩邊有同色)
同理可以得到f1f1f1的方程
f1i=gi(i+1)2+∑j=0i?1gj(j+1)2f0i?j?1+∑j=0i?3gj(j+2)2f1i?j?3f1_i=g_i(i+1)^2+\sum_{j=0}^{i-1}g_j(j+1)^2f0_{i-j-1}+\sum_{j=0}^{i-3}g_j(j+2)^2f1_{i-j-3}f1i?=gi?(i+1)2+j=0∑i?1?gj?(j+1)2f0i?j?1?+j=0∑i?3?gj?(j+2)2f1i?j?3?
得到f0f0f0和f1f1f1之后,看一下f0,f1f0,f1f0,f1都是最左邊沒有距離為222的邊越過的,但是我們轉換到環上的時候需要考慮這種情況,所以我們設f2if2_if2i?表示左右兩邊的橫跨邊都有同色的,中間距離為iii的權值和。
方程是
f2i=gi(i+2)2+∑j=0i?1gj(j+1)2f0i?j?1+∑j=0j?3gj(j+2)2f1i?j?3f2_i=g_i(i+2)^2+\sum_{j=0}^{i-1}g_j(j+1)^2f0_{i-j-1}+\sum_{j=0}^{j-3}g_j(j+2)^2f1_{i-j-3}f2i?=gi?(i+2)2+j=0∑i?1?gj?(j+1)2f0i?j?1?+j=0∑j?3?gj?(j+2)2f1i?j?3?
然后考慮轉換到行上。
如果只有一個點對距離是nnn,那么貢獻是(n?1)(n-1)(n?1),有nnn種旋轉方法,如果這個點對兩邊沒有同色點,那么方案數是gn?1g_{n-1}gn?1?,否則是gn?3g_{n-3}gn?3?,所以這種情況的方案是(n?1)2n(gn?1+gn?3)(n-1)^2n(g_{n-1}+g_{n-3})(n?1)2n(gn?1?+gn?3?)
然后剩下的我們可以先固定1~n+11\sim n+11~n+1,然后枚舉第二個距離為nnn的點對。設為iii,那貢獻就是i(i?1)2(gi?1f0n?i?1+2gi?2f1n?i?2+gi?3f2n?i?3)i(i-1)^2(g_{i-1}f0_{n-i-1}+2g_{i-2}f1_{n-i-2}+g_{i-3}f2_{n-i-3})i(i?1)2(gi?1?f0n?i?1?+2gi?2?f1n?i?2?+gi?3?f2n?i?3?)
然后前面求f0,f1,f2f0,f1,f2f0,f1,f2都可以用分治NTTNTTNTT搞。
時間復雜度O(nlog?2n)O(n\log^2 n)O(nlog2n)
如果用生成函數再推推可以分別得到O(n)O(n)O(n)和O(nlog?n)O(n\log n)O(nlogn)的方法。
還有可以用生成函數發現這是一個161616項的線性遞推式,打出前面的表再用高斯消元得到系數,可以把時間優化到logloglog級別
路還很長啊
code
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=2e5+10,P=998244353; ll n,m,r[N],g[N],h[3][N],f[3][N]; ll t[3][N],T[2][N],z[4][N]; ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans; } void Glen(ll n){m=1;while(m<=n)m<<=1;for(ll i=0;i<m;i++)r[i]=(r[i>>1]>>1)|((i&1)?(m>>1):0);return; } void NTT(ll *f,ll op){for(ll i=0;i<m;i++)if(i<r[i])swap(f[i],f[r[i]]);for(ll p=2;p<=m;p<<=1){ll len=(p>>1),tmp=power(3,(P-1)/p);if(op==-1)tmp=power(tmp,P-2);for(ll k=0;k<m;k+=p){ll buf=1;for(ll i=k;i<k+len;i++){ll tt=buf*f[i+len]%P;f[i+len]=(f[i]-tt+P)%P;f[i]=(f[i]+tt)%P;buf=buf*tmp%P;}}}if(op==-1){ll inv=power(m,P-2);for(ll i=0;i<m;i++)f[i]=f[i]*inv%P;}return; } void CDQ(ll l,ll r){if(l==r){(f[0][l]+=h[0][l])%=P;(f[1][l]+=h[1][l])%=P;return;}ll mid=(l+r)>>1;CDQ(l,mid);Glen((r-l+1)*2);for(ll i=0;i<m;i++)t[0][i]=t[1][i]=t[2][i]=T[0][i]=T[1][i]=0;for(ll i=0;i<=r-l+1;i++)t[0][i]=h[0][i],t[1][i]=h[1][i],t[2][i]=h[2][i];for(ll i=0;i<=mid-l;i++)T[0][i]=f[0][i+l],T[1][i]=f[1][i+l];NTT(t[0],1);NTT(t[1],1);NTT(t[2],1);NTT(T[0],1);NTT(T[1],1);for(ll i=0;i<m;i++){z[0][i]=t[0][i]*T[0][i]%P,z[1][i]=t[1][i]*T[1][i]%P;z[2][i]=t[1][i]*T[0][i]%P,z[3][i]=t[2][i]*T[1][i]%P;}NTT(z[0],-1);NTT(z[1],-1);NTT(z[2],-1);NTT(z[3],-1);for(ll i=0;i<=r-l+1;i++){if(l+i+1>mid&&l+i+1<=r){f[0][l+i+1]=(f[0][l+i+1]+z[0][i])%P;f[1][l+i+1]=(f[1][l+i+1]+z[2][i])%P;}if(l+i+3>mid&&l+i+3<=r){f[0][l+i+3]=(f[0][l+i+3]+z[1][i])%P;f[1][l+i+3]=(f[1][l+i+3]+z[3][i])%P;}}CDQ(mid+1,r);return; } void solve(ll l,ll r){if(l==r){(f[2][l]+=h[2][l])%=P;return;}ll mid=(l+r)>>1;solve(l,mid);Glen((r-l+1)*2);for(ll i=0;i<m;i++)t[1][i]=t[2][i]=T[0][i]=T[1][i]=0;for(ll i=0;i<=r-l+1;i++)t[1][i]=h[1][i],t[2][i]=h[2][i];for(ll i=0;i<=mid-l;i++)T[0][i]=f[1][l+i],T[1][i]=f[2][l+i];NTT(t[1],1);NTT(t[2],1);NTT(T[0],1);NTT(T[1],1);for(ll i=0;i<m;i++){z[0][i]=t[1][i]*T[0][i]%P;z[1][i]=t[2][i]*T[1][i]%P;}NTT(z[0],-1);NTT(z[1],-1);for(ll i=0;i<r-l+1;i++){if(l+i+1>mid&&l+i+1<=r)(f[2][l+i+1]+=z[0][i])%=P;if(l+i+3>mid&&l+i+3<=r)(f[2][l+i+3]+=z[1][i])%=P;}solve(mid+1,r);return; } signed main() {freopen("a.in","r",stdin);freopen("a.out","w",stdout);scanf("%lld",&n);g[0]=g[2]=1;for(ll i=4;i<=n;i++)g[i]=(g[i-4]+g[i-2])%P;for(ll i=0;i<=n;i++){h[0][i]=g[i]*i%P*i%P;h[1][i]=g[i]*(i+1)%P*(i+1)%P;h[2][i]=g[i]*(i+2)%P*(i+2)%P;}CDQ(0,n);solve(0,n);ll ans=(g[n-1]+g[n-3])*(n-1)%P*(n-1)%P*n%P;for(ll i=2;i<n-1;i++){ll tmp=g[i-1]*f[0][n-i-1]%P;tmp=(tmp+2*g[i-2]*f[1][n-i-2]%P)%P;tmp=(tmp+g[i-3]*f[2][n-i-3]%P)%P;tmp=tmp*i%P*(i-1)%P*(i-1)%P;ans=(ans+tmp)%P;}printf("%lld\n",ans);return 0; }總結
以上是生活随笔為你收集整理的CF848E-Days of Floral Colours【dp,分治NTT】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 520贺卡怎么写20字 520贺卡内容句
- 下一篇: 怎么查看需要回答问题的qq相册