Links: http://acm.hdu.edu.cn/showproblem.php?pid=4641
Test instructions: There is a string with a length of not more than 5e4, Q (q<=2e5) times operation;
Operation is divided into: 1 ch to insert a character at the end of the string ch; 2 indicates the number of different substrings of the current string that are not smaller than the number of k times;
Idea: Sam on-line solution;
For each time a character x is found to be inserted into the SAM, we know that pre[p] contains the number of suffix strings of the TX STEP[PRE[NP]], then only need to update the number of occurrences of these strings after each insert CNT;
Since right (FA) has no intersection with Right (R) (max (FA) = min (r)-1), it needs to be recursively pushed to root, but root cannot calculate because root does not represent a suffix, just an init state;
Another point is that when copying the information of Q into the NQ, the main information of CNT is also copied in the past;
#include <iostream>#include<cstdio>#include<cstring>using namespacestd;#defineMAXN 100007#defineSigma_size 26structsam{intsz,tot,last,k; intg[maxn<<1][sigma_size],pre[maxn<<1],step[maxn<<1]; intvs[maxn<<1],cnt[maxn<<1]; voidNewNode (ints) {step[++SZ] =s; PRE[SZ]=0; VS[SZ]= Cnt[sz] =0; memset (G[sz],0,sizeof(G[sz])); } voidinit () {tot=0; SZ=0; Last =1; NewNode (0); } intIdxCharCH) {returnCH-'a';} voidInsert (Charch) {NewNode (Step[last]+1); intv = IDX (ch), p = last, NP =sz; while(P &&!)G[p][v]) G[p][v]= Np,p = Pre[p];//know the ancestor node that finds the edge of the right collection that contains x if(p) {intQ =G[p][v]; if(Step[q] = = Step[p] +1) PRE[NP]=Q; Else{newNode (step[p]+1); intNQ = sz;//NQ Replace Q node for(inti =0; I < sigma_size;i++) G[nq][i]=G[q][i]; CNT[NQ]= Cnt[q];//**PRE[NQ] =Pre[q]; PRE[NP]= Pre[q] =NQ; while(P && g[p][v] = =q) g[p][v]= Nq,p =Pre[p]; } } ElsePRE[NP] =1; for(intAux = np;aux! =1&&!vs[aux];aux =Pre[aux]) { if(++cnt[aux] >=k) {Tot+ = Step[aux]-Step[pre[aux]]; Vs[aux]=true;//the child string of the parent node has been added to the tot}} last=NP; }}sa;CharSTR[MAXN];intMain () {intn,q; while(SCANF ("%d%d%d", &n,&q,&sa.k) = =3) {scanf ("%s", str); Sa.init (); intLen =strlen (str); for(inti =0; I < len;i++) {SA. Insert (Str[i]); } intop; Charch[2]; while(q--) {scanf ("%d",&op); if(OP &1) {scanf ("%s", CH); Sa. Insert (ch[0]); } Elseprintf"%d\n", Sa.tot); } }}
HDU 4641 k-string Sam Understanding