[atARC094F]Normalization

考慮$s$能變成$t$的必要條件(假設$s\ne t$):c++

1.$s$中存在一對相鄰字符不一樣ide

2.$|s|=|t|$且若將a-c對應爲0-2,則字符模3同餘;spa

3.$t$中存在一對相鄰兩個字符相同字符串

同時,對於$|s|\ge 4$,這個充分條件也是必要條件,證實以下:it

概括,對於$|s|=4$暴力驗證,不然考慮經過若干次操做將$s$首或尾的字符與$t$相同,而後刪去這個字符class

具體的構造:若初始相同,直接刪去便可,不然強制$s_{2}=s_{3}=除去s_{1}和t_{1}的另外一種字符$,而後經過$s_{4}$調整模數相等,再令$s_{5}=...=s_{|s|}=a$便可,先將$s[2,|s|]$變爲該字符串,而後再操做一次即相同im

同時爲了保證第2個性質,若僅在首部出現相鄰的相同字符,選擇刪去尾部,且因爲$|s|\ge 4$,首尾相同的部分必然不會重複,所以合法img

對於第一個條件直接斷定(注意還有$s=t$的1種)便可,不然令$f[i][j][k][p]$表示$t$中前$i$個字符和模3爲$j$,最後一個字符爲$k$,是否出現過相鄰字符相同的方案數,轉移分類討論便可di

特別的,若是$s$中沒有相鄰兩個字符,但$t=s$仍然是合法解,答案要加1view

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk= watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 200005
 4 #define mod 998244353
 5 int n,sum,ans,vis[3][3][3],f[N][3][3][2];
 6 char s[N];
 7 void dfs(int a,int b,int c){
 8     if (vis[a][b][c])return;
 9     vis[a][b][c]=1;
10     ans++;
11     if (a!=b)dfs(3-a-b,3-a-b,c);
12     if (b!=c)dfs(a,3-b-c,3-b-c);
13 }
14 int main(){
15     scanf("%s",s);
16     n=strlen(s);
17     if (n==2){
18         printf("%d",1+(s[0]!=s[1]));
19         return 0;
20     }
21     if (n==3){
22         dfs(s[0]-'a',s[1]-'a',s[2]-'a');
23         printf("%d",ans);
24         return 0;
25     }
26     bool flag=0;
27     for(int i=1;i<n;i++)
28         if (s[i]!=s[0]){
29             flag=1;
30             break;
31         }
32     if (!flag){
33         printf("1");
34         return 0;
35     }
36     for(int i=0;i<3;i++)f[0][i][i][0]=1;
37     for(int i=1;i<n;i++)
38         for(int j=0;j<3;j++)
39             for(int k=0;k<3;k++)
40                 for(int l=0;l<3;l++)
41                     for(int p=0;p<2;p++)
42                         f[i][j][k][(p|(l==k))]=(f[i][j][k][(p|(l==k))]+f[i-1][(j+3-k)%3][l][p])%mod;
43     sum=0,ans=1;
44     for(int i=0;i<n;i++)sum=(sum+s[i]-'a')%3;
45     for(int i=1;i<n;i++)ans&=(s[i]!=s[i-1]);
46     for(int i=0;i<3;i++)ans=(ans+f[n-1][sum][i][1])%mod;
47     printf("%d",ans);
48 }
View Code
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息