string matching

string matching

exkmp

#include<bits/stdc++.h>
using namespace std;
const int maxn=1000005;
int Nex[maxn],extend[maxn];
void getNex(char str[])
{
    int i=0,j,po,len=strlen(str);
    Nex[0]=len;
    while(str[i]==str[i+1]&&i+1<len)
    {
        i++;
    }
    Nex[1]=i;
    po=1;
    for(i=2; i<len; i++)
    {
        if(Nex[i-po]+i<Nex[po]+po)
        {
            Nex[i]=Nex[i-po];
        }
        else
        {
            j=Nex[po]+po-i;
            if(j<0)j=0;
            while(i+j<len&&str[j]==str[j+i])
            {
                j++;
            }
            Nex[i]=j;
            po=i;
        }
    }
}
void Extend(char s1[],char s2[])
{
    int i=0,j,po,len=strlen(s1),l2=strlen(s2);
    getNex(s2);
    while(s1[i]==s2[i]&&i<l2&&i<len)
    {
        i++;
    }
    extend[0]=i;
    po=0;
    for(i=1; i<len; i++)
    {
        if(Nex[i-po]+i<extend[po]+po)
        {
            extend[i]=Nex[i-po];
        }
        else
        {
            j=extend[po]+po-i;
            if(j<0)j=0;
            while(i+j<len&&j<l2&&s1[j+i]==s2[j])j++;
            extend[i]=j;
            po=i;
        }
    }
}
char s[1000005];
char t[1000005];
int main()
{
   freopen("1.in","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(extend,0,sizeof extend);
        memset(Nex,0,sizeof Nex);
        scanf("%s",s);
        strcpy(t,s);
        Extend(s,t);
        int n=strlen(s);
        long long ans=0;
        //cout<<s<<t<<endl;
        for(int i=1; i<=n-2; i++)
        {
            if(i+extend[i]==n)
                ans+=extend[i];
            else
            ans+=extend[i]+1;
            //cout<<extend[i]<<" "<<i<<" "<<n-1<<'\n';
        }
        if(n>1)
        ans+=1;
        cout<<ans<<'\n';
    }
}

 

posted @ 2019-08-06 22:27  liulex  阅读(228)  评论(0编辑  收藏  举报