HDU 6629 (Hangzhou Electricity Fifth Field 1007, 2019) Permutation 2 (Extended kmp)

Keywords: ascii

Question: Seek strings s[i... Len_1] and s[0... Comparisons of len_1]i>0 for the longest common prefix length

Solution: At that time, the AC automaton was directly used and then the fail pointer was used. As a result, the input character was ASCII, which was super memory. The sum of the longest common prefix of each suffix can be obtained by extending kmp. Note that the current subscript plus the longest prefix length exceeds the string length of ans--.
Because it is the number of comparisons.

Extended KMP solves the following problems:

Define the parent string S and the substring T, the length of S is n, and the length of T is m.

Find the longest common prefix for each suffix of string T and string S;

That is to say, there is an extended array: extend[i] denotes the longest common prefix of T and S[i,n-1], requiring all extend[i] (0 <= I < n).

The longest common prefix length of T[i,m-1] and T is represented by an auxiliary array next[i]

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int K=1000005;
int nt[K],extand[K];
char S[K],T[K];
int a[K];
ll ans;
void Getnext(char *T,int *next)
{
    int len=strlen(T),a=0;
    next[0]=len;
    while(a<len-1 && T[a]==T[a+1]) a++;
    next[1]=a;
    a=1;
    for(int k=2; k<len; k++)
    {
        int p=a+next[a]-1,L=next[k-a];
        if( (k-1)+L >= p)
        {
            int j = (p-k+1)>0 ? (p-k+1) : 0;
            while(k+j<len && T[k+j]==T[j]) j++;
            next[k]=j;
            a=k;
        }
        else
            next[k]=L;
    }
}
void GetExtand(char *S,char *T,int *next)
{
    Getnext(T,next);
    int slen=strlen(S),tlen=strlen(T),a=0;
    int MinLen = slen < tlen ? slen : tlen;
    while(a<MinLen && S[a]==T[a]) a++;
    extand[0]=a;
    a=0;
    for(int k=1; k<slen; k++)
    {
        int p=a+extand[a]-1, L=next[k-a];
        if( (k-1)+L >= p)
        {
            int j= (p-k+1) > 0 ? (p-k+1) : 0;
            while(k+j<slen && j<tlen && S[k+j]==T[j]) j++;
            extand[k]=j;
            a=k;
        }
        else
            extand[k]=L;
    }
}
//These are templates.
int main(void)
{
	int tl;scanf("%lld",&tl);
    while(tl--)
    {
    	memset(nt,0,sizeof(nt));
    	memset(extand,0,sizeof(extand));
    	memset(a,0,sizeof(a));
		scanf("%s",S);
    	ans = 0;
    	strcpy(T,S);
        GetExtand(S,T,nt);
        int len = strlen(T);
        queue<int> id;
		ans = 0;
		ans+=len-1;
		for(int i=1; i<len; i++) {
			if(nt[i]!=0) {
				ans+=nt[i];
				if(i+nt[i]>=len)ans--;
			}
		}
		printf("%lld\n",ans);
    }
    return 0;
}
/*
3
_Happy_New_Year_
ywwyww
zjczzzjczjczzzjc

17
7
32
*/

 

Posted by alexanae on Wed, 09 Oct 2019 12:16:58 -0700