Http://codeforces.com/problemset/problem/127/D
Question: Find the eldest son of a string s so that it is the prefix, suffix, and infix of S at the same time.
Idea: there are multiple methods for this question. Here we introduce the Sam method. We first construct the Sam of S. For every state of Sam, set num to the number of characters represented by it in S, R represents the rightmost position of the substring in S (the two quantities are obtained from the bottom up after being sorted by the nature of SAM ). Then use s to perform matching on Sam. Suppose we have already matched the length N. Because the current matched string must be the prefix of S, we only need to determine whether it is an infix or a suffix. What kind of string is a suffix of S? Apparently, a substring with the position of | S | appears in S. If P is in the current state, if p-> r = | S |, it indicates that it must be the suffix of S. To determine whether it is an infix, you only need to check whether it appears more than 3 times in S. Then, after a match, the last substring that meets the first two requirements is required. If not, the output is not. The Code is as follows:
#include <iostream>#include <string.h>#include <stdio.h>#define maxn 2000010#define Smaxn 26#define inf 21000000using namespace std;struct node{ node *par,*go[Smaxn]; int right; int num; int po; int val;}*root,*tail,que[maxn],*top[maxn];int tot;char str[maxn>>1];void add(int c,int l,int po){ node *p=tail,*np=&que[tot++]; np->val=l; np->po=po; while(p&&p->go[c]==NULL) p->go[c]=np,p=p->par; if(p==NULL) np->par=root; else { node *q=p->go[c]; if(p->val+1==q->val) np->par=q; else { node *nq=&que[tot++]; *nq=*q; nq->val=p->val+1; np->par=q->par=nq; while(p&&p->go[c]==q) p->go[c]=nq,p=p->par; } } tail=np;}int c[maxn],len;void init(){ memset(que,0,sizeof(que)); tot=0; len=1; root=tail=&que[tot++];}void solve(int n){ memset(c,0,sizeof(c)); int i; for(i=0;i<tot;i++) c[que[i].val]++; for(i=1;i<len;i++) c[i]+=c[i-1]; for(i=0;i<tot;i++) top[--c[que[i].val]]=&que[i]; for(node *p=root;;p=p->go[str[p->val+1]-'a']) { p->num=1; p->right=p->po; //printf("f"); if (p->val==len-1)break; } for(i=tot-1;i>=0;i--) { node *p=top[i]; if(p->right==0) { p->right=p->po; } if(p->par) { node *q=p->par; q->num+=p->num; if(q->right==0||q->right<p->right) q->right=p->right; } } int po=0; node *p=root; for(i=1;i<=n;i++) { p=p->go[str[i]-'a']; if(str[i]==str[n]) { if(p->right==n&&p->num>=3) po=i; } } if(po==0) printf("Just a legend\n"); else { for(i=1;i<=po;i++) printf("%c",str[i]); printf("\n"); }}int main(){ freopen("dd.txt","r",stdin); scanf("%s",str+1); int i,l=strlen(str+1); init(); for(i=1;i<=l;i++) { add(str[i]-'a',len++,i); } solve(l); return 0;}