一道NOI的KMP写了六个半小时

这道题也很恼火

一开始是用while循环 ne[ne[j]] 不停的推

然后发现可以用num数组记录前缀的前缀的

WA了四五法,可能是用string来写,下标从0开始总是会有点缺陷

下定决心以后都用char数组来做kmp

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1e6 + 100;
const ll MOD = 1000000007;
ll n, k;
char p[N];
ll ne[N],num[N];
void pre()
{
    for (ll i = 2, j = 0; i <= n; i++)
    {
        while (j && p[i] != p[j+1])
            j = ne[j ];
        if (p[i] == p[j+1])
            j++;
        ne[i] = j;
       
    }
    for (ll i=1;i<=n;i++) num[i]=num[ne[i]]+1;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> k;
    while (k--)
    {
        memset(ne,0,sizeof ne);
        memset(num,0,sizeof num);
        
        cin >> (p+1);
        n = strlen(p+1);
        pre();
        //for (ll i=0;i<n;i++)
         //   cout<<i<<" "<<ne[i]<<endl;
        ll ans = 1;
        for (int i = 2,j=0; i <= n; i++)
        {
            while(j&&p[i]!=p[j+1]) j=ne[j];
            if (p[i]==p[j+1])
            {
                j++;
            }
            while(((j)<<1)>(i)) j=ne[j];//,cout<<j<<endl;
            //cout<<j<<" "<<num[j]<<endl;
            ans=ans*(num[j]+1)%MOD;
            //cout<<ans<<endl;


        }
        cout<<ans << endl;
    }

    return 0;
}
//记录一下第一次一个程序写了6个半小时

周日上海站要打铁了...有点小慌...

posted @ 2020-12-10 20:41  william4s  阅读(87)  评论(0)    收藏  举报