您的位置:首页 > 其它

bzoj3670 [noi2014] 动物园(kmp改编)

2017-07-23 22:57 405 查看
解释写代码里了。。noi出这样的题可是很神奇哟。(像我这样的蒟蒻可能场上也不一定能写出来吧。。)

#include <cstdio>
#include <cstring>
#define ll long long
#define N 1000010
#define mod 1000000007
int tst,fail
,cnt
,m;
char s
;
inline void getfail(){
//cnt[i]记录失配多少次到0,即前后缀相同的个数+1
//num[i]其实就是第一个匹配上的k的cnt[k]
int k=0;fail[1]=0;cnt[1]=1;
for(int i=2;i<=m;++i){
while(k&&s[k+1]!=s[i]) k=fail[k];
if(s[k+1]==s[i]) ++k;
fail[i]=k;
cnt[i]=cnt[k]+1;
}
}
int main(){
// freopen("a.in","r",stdin);
scanf("%d",&tst);
while(tst--){
scanf("%s",s+1);m=strlen(s+1);int ans=1;
getfail();int k=0;
for(int i=2;i<=m;++i){
while(k&&s[k+1]!=s[i]) k=fail[k];
if(s[k+1]==s[i]) ++k;
while((k<<1)>i) k=fail[k];//去重叠
ans=(ll)ans*(cnt[k]+1)%mod;
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: