[BZOJ3670][Noi2014]动物园 && KMP

来源:互联网 发布:林更新 网络 编辑:程序博客网 时间:2024/04/30 11:12

不要问我为什么不从s开始读 我试了N久没试出来 然后用s+1开始读就爽爽哒

在构造fail数组之后递推构造num数组(与题目有所不同的是这里的num指的是由当前位置失匹num次后会回到1) 假设某个fail值的位置j  并且j*2 > i 说明肯定有重复的部分 继续寻找前一个fail值 

#include<cstdio>#include<algorithm>#include<cstring>#include<iostream>#include<queue>#include<set>#define SF scanf#define PF printfusing namespace std;typedef long long LL;const int MAXN = 1000000;const int MOD = 1000000007;char s[MAXN+10];int f[MAXN+10], num[MAXN+10], n, ans;void GetFail() {    num[1] = 1;    int fail = 0;    for(int i = 2; i <= n; i++) {        while(fail && s[fail+1] != s[i]) fail = f[fail];        if(s[fail+1] == s[i]) fail++;        f[i] = fail; num[i] = num[fail]+1;    }    fail = 0;    for(int i = 2; i <= n; i++) {        while(fail && s[fail+1] != s[i]) fail = f[fail];        if(s[fail+1] == s[i]) fail++;        while( (fail << 1) > i && fail) fail = f[fail];        ans = 1LL * ans * (num[fail]+1) % MOD;    }}int main() {    int _T; SF("%d", &_T); while(_T--) {        ans = 1;        SF("%s", s+1);        n = strlen(s+1);        GetFail();        PF("%d\n", ans);    }}



0 0
原创粉丝点击