为了方便,以下默认字符集为$\{A,R,C\}$
将操作逆向,即将形如ARC的子串变为任意字符,求$T$在$k$步内能得到的$S$数量
考虑给定$S$,如何判定$S$能否被$T$在$k$步内得到——
将任意字符用?表示,称两个字符串匹配即将?替换后两者相同,那么操作即将能与ARC匹配的子串变为???,并判定$k$步内能否得到与$S$匹配的字符串
(注意到当?为了之后的操作而确定后,该次操作后其又会任意)
考虑"能与ARC匹配的字符串",显然共有8种,且其中A?C不会出现、???无意义
换言之,?的拓展形式即以下三种:
1.将ARC变为???
2.将一段?左侧的AR/A、右侧的RC/C替换为??/?
3.将两段?之间的R替换为?
重复此过程直至无法拓展,并将每一次拓展的用()表示、无法拓展的部分用(X)代替
考虑其最终的形式,总是形如(X/空)P(R/X/空)P(X/空)(其中P=(AR/A)(ARC)(RC/C),加粗的部分可以重复),且不难证明这样的划分方式是唯一的
考虑对$T$以此法划分,并用$f_{i,j,0/1/2}$表示前$i$个部分中选$j$个、最后一个是否选择以及是否是独立的ARC(注意并不指倒数第2个不选,形如ARCARC后者也是独立的)对应的$S$方案数
关于转移参考代码(即选择合理且某些部分要求严格不同),时间复杂度为$o(|T|^{2})$,可以通过

1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 5005 4 #define mod 998244353 5 #define ll long long 6 vector<pair<int,int> >v; 7 int n,m,ans,inv[N],a[N],cnt[N],vis[N],f[N][N][3],len[6]={3,2,1,2,1,1}; 8 char s[N],t[6][3]={{'A','R','C'},{'A','R','?'},{'A','?','?'},{'?','R','C'},{'?','?','C'},{'?','R','?'}}; 9 int main(){ 10 inv[0]=inv[1]=1; 11 for(int i=2;i<N;i++)inv[i]=(ll)(mod-mod/i)*inv[mod%i]%mod; 12 scanf("%s%d",s+1,&m),n=strlen(s+1); 13 while (1){ 14 bool Flag=0; 15 for(int i=1;i<=n-2;i++){ 16 for(int j=0;j<6;j++){ 17 bool flag=0; 18 for(int k=0;k<3;k++) 19 if (s[i+k]!=t[j][k])flag=1; 20 if (!flag){ 21 Flag=1; 22 int p=i+2; 23 if (s[p]=='?')p--; 24 if (s[p]=='?')p--; 25 v.push_back(make_pair(p,j)); 26 for(int k=0;k<3;k++)s[i+k]='?'; 27 break; 28 } 29 } 30 if (Flag)break; 31 } 32 if (!Flag)break; 33 } 34 sort(v.begin(),v.end()); 35 n=v.size(); 36 for(int i=1;i<=n;i++){ 37 a[i]=v[i-1].second; 38 cnt[i]=1; 39 for(int j=0;j<len[a[i]];j++)cnt[i]*=3; 40 } 41 f[0][0][0]=1; 42 for(int i=1;i<=n;i++){ 43 for(int j=0;j<=i;j++)f[i][j][0]=f[i-1][j][0]; 44 if ((i==1)||(a[i-1]==0)||(a[i-1]==3)||(a[i-1]==4)){ 45 for(int j=0;j<=i;j++) 46 for(int p=1;p<3;p++)f[i][j][0]=(f[i][j][0]+f[i-1][j][p])%mod; 47 } 48 if (!a[i]){ 49 if ((a[i-1]!=1)&&(a[i-1]!=2)&&(a[i-1]!=5)){ 50 for(int j=1;j<=i;j++) 51 for(int p=0;p<3;p++)f[i][j][2]=(f[i][j][2]+(ll)(cnt[i]-1)*f[i-1][j-1][p])%mod; 52 } 53 else{ 54 for(int j=1;j<=i;j++){ 55 f[i][j][1]=(ll)cnt[i]*(f[i-1][j-1][1]+f[i-1][j-1][2])%mod; 56 f[i][j][2]=(ll)(cnt[i]-1)*f[i-1][j-1][0]%mod; 57 } 58 } 59 continue; 60 } 61 if ((a[i]==1)||(a[i]==2)){ 62 if ((a[i-1]!=1)&&(a[i-1]!=2)&&(a[i-1]!=5)){ 63 for(int j=1;j<=i;j++) 64 for(int p=0;p<3;p++)f[i][j][1]=(f[i][j][1]+(ll)(cnt[i]-1)*f[i-1][j-1][p])%mod; 65 } 66 else{ 67 for(int j=1;j<=i;j++)f[i][j][1]=(ll)(cnt[i]-1)*f[i-1][j-1][0]%mod; 68 for(int j=1;j<=i;j++)f[i][j][1]=(f[i][j][1]+(ll)cnt[i]*(f[i-1][j-1][1]+f[i-1][j-1][2]))%mod; 69 } 70 } 71 else{ 72 if (a[i-1]){ 73 int s=(ll)(cnt[i]-1)*(inv[cnt[i-1]-1]+1)%mod; 74 for(int j=1;j<=i;j++)f[i][j][1]=(ll)s*(f[i-1][j-1][1]+f[i-1][j-1][2])%mod; 75 } 76 else{ 77 int s=cnt[i]-1; 78 for(int j=1;j<=i;j++)f[i][j][1]=(ll)s*f[i-1][j-1][1]%mod; 79 s=(ll)s*(inv[cnt[i-1]-1]+1)%mod; 80 for(int j=1;j<=i;j++)f[i][j][1]=(f[i][j][1]+(ll)s*f[i-1][j-1][2])%mod; 81 } 82 } 83 } 84 for(int i=0;i<=m;i++) 85 for(int j=0;j<3;j++)ans=(ans+f[n][i][j])%mod; 86 printf("%d\n",ans); 87 return 0; 88 }