AGC027E ABBreviate
Link
设\(v(a)=1,v(b)=2\),那么不管如何操作,所有字符的权值和在\(\bmod3\)意义下不变。
我们用\(w(s)\)来表示字符串\(s\)所有字符的权值之和\(\bmod3\)。
考虑字符串\(s\)能否变为字符串\(t(t\ne s)\)。
倒序枚举\(t\)中的每一个字符,取\(s\)的一段满足可以变成该字符的最短后缀。如果能够做到最后,那么\(s\)会剩下一个前缀\(pre\),如果\(w(pre)=0\)那么我们称成功匹配。
那么字符串\(s\)能变为字符串\(t\)的充要条件就是能够成功匹配且\(s\)中存在两个相邻且相同的字符。
然后我们先特判\(s\)中不存在两个相邻且相同的字符的情况,这时答案为\(1\)。
设\(f_i\)表示\(pre_i\)能够变成的\(t\)的个数,转移就枚举\(i\)所在段最后变成哪个字符,同时还要特判把整个字符串变成一个字符的情况。
#include<cstdio>
#include<cstring>
const int N=100007,P=1000000007;
char str[N];int a[N],f[N],las[3];
int main()
{
scanf("%s",str+1);int n=strlen(str+1),flg=0;
for(int i=1;i<=n;++i) if(a[i]=(a[i-1]+str[i]-'a'+1)%3,str[i]==str[i-1]) flg=1;
if(!flg) return puts("1"),0;;
for(int i=1;i<=n;++i) f[i]=(1ll*f[las[0]]+f[las[1]]+f[las[2]]+(a[i]>=1)-f[las[a[i]]]+P)%P,las[a[i]]=i;
printf("%d",f[n]);
}