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 ",res); 26 }