AGC027E ABBreviate

Link
(v(a)=1,v(b)=2),那么不管如何操作,所有字符的权值和在(mod3)意义下不变。
我们用(w(s))来表示字符串(s)所有字符的权值之和(mod3)
考虑字符串(s)能否变为字符串(t(t e 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]);
}
原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12747288.html