1. 程式人生 > >Codeforces Educational Codeforces Round 52

Codeforces Educational Codeforces Round 52

Problem E

題意:

戳這裡

長度為$n$的串 ,串的字符集為$A$

還有一個序列$B$,元素個數為$m$, 保證$B_{1}<B_{2}<...<B_{m}$

現在定義一種操作,每次 可以選擇一個$B_{i}$,使串先翻轉,再把除了前$B_{i}$和後$B_{i}$的串翻轉回來.

定義兩個串相等 ,當一個串經過若干次操作可以變為另一個串.

 

求長度為$n$的串中 有多少本質不同的的串.

$n,A<=1e9,m<=min\{n/2,2e5 \}$

 

題解:

模擬大法好啊!! 

經過模擬操作可以發現經過若干次操作之後

①第$i$個字元只可能在第$i$個或第$n-i+1$個位置

②$B_{i}$所分成的$m$段中,相同段的狀態一定是一樣的(都翻轉或都不翻轉)

③$m$段的狀態可以是任意的 互不影響(從最大的那一段開始翻/不翻 以此類推可以操作出所有方案)

也就是每一段都是獨立的.那麼答案就是每一段的不同方案的累乘.

長度為$len$的一段的方案數是 $\frac{A^{2*len}+A^{len}}{2}$

 1 #include<bits/stdc++.h>
 2 const int M=2e5+5;
 3 const int P=998244353;
 4 int
B[M],n,m,A; 5 int Pow(int x,int y){ 6 int res=1; 7 while(y){ 8 if(y&1)res=1ll*res*x%P; 9 x=1ll*x*x%P; 10 y>>=1; 11 } 12 return res; 13 } 14 int main(){ 15 //freopen("data.txt","r",stdin); 16 scanf("%d %d %d",&n,&m,&A); 17 int
i,res=1,len,inv=Pow(2,P-2); 18 for(i=1;i<=m;i++)scanf("%d",&B[i]); 19 B[0]=0; 20 for(i=m;i>=1;i--){ 21 len=B[i]-B[i-1]; 22 res=1ll*(Pow(A,2*len)+Pow(A,len))%P*inv%P*res%P; 23 } 24 res=1ll*res*Pow(A,n-2*B[m])%P; 25 printf("%d\n",res); 26 }
View Code