【洛谷P2375】动物园【KMP】

题目大意:

题目链接:https://www.luogu.org/problemnew/show/P2375
求一个字符串前缀和后缀互不相交的 n e x t 数组之积 m o d 1000000007


思路:

前缀和后缀互不相交,其实就是说 n e x t [ i ] 必须 [ i / 2 ] ,( [   ] )。
那么就先求出一个正常的 n e x t 数组,然后再多增加一个循环,与求 n e x t 数组很像,只不过多了一行,保证 n e x t 数组只有 i 的一半:

w h i l e ( j 2 > i + 1 ) j = n e x t [ j ]

然后就求出 s u m 的值即可。


代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#define MOD 1000000007ll
using namespace std;

long long sum;
int t,n,j,next[1000001],ans[1000001];
char s[1000001];

int main()
{
    scanf("%d",&t);
    while (t--)
    {
        memset(next,0,sizeof(next));
        memset(ans,0,sizeof(ans));
        cin>>s;
        n=strlen(s);
        j=0;
        sum=1;
        ans[1]=1;  //初始化
            for (int i=1;i<n;i++)  //求next数组不解释
        {
            while (j&&s[j]!=s[i]) j=next[j];
            if (s[i]==s[j]) j++;
            next[i+1]=j;
            ans[i+1]=ans[j]+1;
        }
        j=0;
        for (int i=1;i<n;i++)  //求出只有一半的next数组
        {
            while (j&&s[j]!=s[i]) j=next[j];
            if (s[i]==s[j]) j++;
            while (j*2>i+1) j=next[j];
            sum*=((long long)ans[j]+1);  //求答案
            sum%=MOD;
        }
        cout<<sum<<"\n";
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/SSL_ZYC/article/details/81749142