Test instructions: Find the oldest string in a string that can overlap at least m times, and find the starting position of the last occurrence of the string.
Look for the Internet and there is no solution to Sam's approach. I'll take a moment.
First, the nodes on each Sam need to save two more values: CNT and right. CNT stands for the state right collection size, which is the largest value (see CLJ ppt) in the Well collection, and the initial value is Val.
In fact, if the node is a copy of the node (that is, the code NQ) The initial value should be the original node right? It doesn't matter, we always update to the
Then we have two approaches: 1. The right collection size of the parent node is updated each time the violence is inserted.
2, after inserting the unified update (such as Spoj 8222)
The first approach was problematic, and the complexity was not guaranteed, so the tle was duly completed.
The second kind is relatively troublesome. Because the Val value is large to update the CNT with a small Val value, the first order is based on the Val value. Then since all the substrings are a suffix of a prefix, we set the CNT of the prefix to 1 (from the diagram on the net, the most intermediate row node CNT value is all set to 1, the other is set to 0), according to Val from large to small update CNT and right.
Afraid to kneel down, so the M=1 was a special award. Actually, it's also possible not to judge.
1#include <cstdio>2#include <algorithm>3#include <cstring>4 Const intmaxn=40000+5;5 Const intSigma_size= -;6 Const intinf=~0U>>1;7 structstate{8state* go[sigma_size],*Suf;9 intVal,cnt,right;TenState (): Suf (0) {val=cnt=0; Memset (Go,0,sizeofgo);} One}*root,*Last ; AState mem[maxn<<1],*cur; - intAns1,ans2; - intm; theInlinevoidInit () - { -ans1=-1; -Cur=Mem; +mem[0]=State (); -last=root=cur++; + } AInlinevoidExtendintW) at { -state* p=last,*np=cur++; -*np=State (); -np->right=np->val=p->val+1; - while(P &&!p->go[w]) p->go[w]=np,p=p->Suf; - if(!p) np->suf=Root; in Else - { tostate* q=p->Go[w]; + if(q->val==p->val+1) np->suf=Q; - Else the { *state* nq=cur++; $*nq=State ();Panax Notoginsengmemcpy (Nq->go,q->go,sizeofQ->go); -nq->right=nq->val=p->val+1; theNq->suf=q->Suf; +q->suf=np->suf=NQ; A while(P && p->go[w]==q) p->go[w]=nq,p=p->Suf; the } + } -last=NP; $ } $InlineintIdxCharc) - { - returnC-'a'; the } - CharS[MAXN];Wuyi intN; thestate* pt[maxn<<1]; - voidWork () Wu { - Static intws[maxn<<1]; Aboutstate*T; $ for(intI=0; i<=n;++i) ws[i]=0; - for(t=mem+1; t!=cur;++t) ++ws[t->Val]; - for(intI=1; i<=n;++i) ws[i]+=ws[i-1]; - for(t=cur-1; t!=mem;--t) pt[--ws[t->val]]=T; At=Root; + for(intI=0; i<n;++i) T=t->go[idx (S[i])],t->cnt++; the for(inti=cur-mem-2; i>=0;--i) - { $state* u=Pt[i]; the if(u->cnt>=m) the { the if(U->VAL>ANS1) ans1=u->val,ans2=u->right-u->Val; the Else if(u->val==ans1) Ans2=std::max (ans2,u->right-u->val); - } in if(u->Suf) theU->suf->cnt+=u->cnt,u->suf->right=std::max (u->suf->right,u->Right ); the } About } the intMain () the { the //freopen ("1.in", "R", stdin); + while(SCANF ("%d", &m)!=eof &&m) - { the init ();Bayiscanf"%s", s); then=strlen (s); the if(m==1) - { -printf"%d 0\n", n); the Continue; the } the for(intI=0; i<n;++i) the Extend (IDX (s[i)); - Work (); the if(ans1==-1) puts ("None"); the Elseprintf"%d%d\n", ans1,ans2); the }94 return 0; the}
View Code
POJ 3882/la4513/hdu4080/zoj3395 stammering Aliens "suffix automaton"