zoukankan      html  css  js  c++  java
  • [atARC131F]ARC Stamp

    为了方便,以下默认字符集为$\{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 }
    View Code
  • 相关阅读:
    日报8.18
    Java web项目启动Tomcat报错
    eclipse导入项目报错问题解决方法
    软件架构实践阅读笔记3
    软件架构实践阅读笔记 2
    软件架构实践阅读笔记1
    架构漫谈阅读笔记3
    架构漫谈阅读笔记2
    架构漫谈阅读笔记1
    面向服务的架构SOA
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15667500.html
Copyright © 2011-2022 走看看