Description
Background
Want to KPM that year in order to prevent others casually into his MC, to his PC set up a variety of strange password and verification problems (don't ask me how he set up ...) As a matter of course, he now rightly forgets the password, only to answer the magic of the authentication problem ...
Describe
The problem with KPM was this:
Now define such a concept, if the string s is a suffix of the string C, then we call c a KPM string of S.
The system randomly generates n strings of a...z, numbered by 1...N (S1,S2...,SN), and then tells you sequentially, and then gives you n numbers, respectively k1...kn, for each ki, asks you to find the number of the string in the N string listed in all Si kpm strings, and if there is no small number of ki, replace with 1. (for example, given the string is CD,ABCD,BCD, at this time k1=2, then the "CD" KPM string has "CD", "ABCD", "BCD", the number is the 2nd one of the small number is 2) (PS: If you can in a very fast time to answer all the N ki query , then you can successfully help KPM into MC ~ ~)
Input
The first line an integer n indicates the number of strings
The second line to the N+1 line is a total of n rows, each row includes a string, and the string of line i+1 represents the string with the number I
The next consists of n rows, each containing an integer ki, meaning as shown in the previous question
Output
Consisting of n rows, the line I consists of an integer that represents all the strings of the KPM string of SI in the number of Ki small
Sample Input
3
Cd
Abcd
Bcd
2
3
1
Sample Output2
-1
2
Sample explanation
The "CD" KPM string has "CD", "ABCD", "BCD", numbered in the 2nd, the small number is
2, "ABCD" of the KPM string only one, so the 3rd small number does not exist, "BCD" of the KPM
The string has "ABCD", "BCD", the 1th small number is 2.
Data scope and conventions
Sets the total length of all strings to Len
For 100% of data, 1<=n<=100000,0<len<=300000
Build an AC automaton, get the last pointer, and turn into a tree and convert it into a sub-tree K small problem, write a chairman tree.
#include <cstdio>#include<cctype>#include<queue>#include<cmath>#include<cstring>#include<algorithm>#defineRep (i,s,t) for (int i=s;i<=t;i++)#defineDwn (i,s,t) for (int i=s;i>=t;i--)#defineren for (int i=first[x];i!=-1;i=next[i])using namespacestd;Const intBuffersize=1<< -;Charbuffer[buffersize],*head,*Tail;inlineCharGetchar () {if(head==tail) { intL=fread (Buffer,1, Buffersize,stdin); Tail= (Head=buffer) +M; } return*head++;} InlineintRead () {intx=0, f=1;CharC=GetChar (); for(;! IsDigit (c); C=getchar ())if(c=='-') f=-1; for(; IsDigit (c); C=getchar ()) x=x*Ten+c-'0'; returnx*F;}Const intmaxn=100010;Const intMaxnode=300010;intFirst[maxnode],next[maxnode],val[maxnode],pos[maxn],tot;intch[maxnode][ -],cnt;voidInsertChar* S,intv) {intj=0, C; for(intI=0; s[i];i++) {C=s[i]-'a'; if(!ch[j][c]) ch[j][c]=++CNT; J=Ch[j][c]; } val[++tot]=v; pos[v]=j;next[tot]=first[j];first[j]=tot;}intQ[maxnode],f[maxnode],last[maxnode];intfirst[maxnode],next[maxnode],to[maxnode],e;voidAddedge (intUintv) {to[++e]=v; Next[e]=first[u]; first[u]=e;}voidGetfail () {intL=1, r=0; Rep (c,0, -)if(ch[0][C]) q[++r]=ch[0][c]; while(l<=r) {intx=q[l++]; Rep (c,0, -)if(Ch[x][c]) {intu=ch[x][c],j=f[x];q[++r]=u; while(J&&!ch[j][c]) j=F[j]; F[u]=ch[j][c];last[u]=first[f[u]]?F[u]:last[f[u]]; }} rep (I,1, CNT)if(First[i]) Addedge (last[i],i);}CharS[maxnode];intls[maxn* -],rs[maxn* -],siz[maxn* -],tot,l[maxnode],r[maxnode];introot[maxnode],cur;voidBuildint& Y,intXintLintRintPOS) {Siz[y=++tot]=siz[x]+1;if(L==R)return; intMid=l+r>>1; ls[y]=ls[x];rs[y]=Rs[x]; if(pos<=mid) build (Ls[y],ls[x],l,mid,pos); ElseBuild (rs[y],rs[x],mid+1, R,pos);}intQueryintYintXintLintRintk) {if(siz[y]-siz[x]<k)return-1; if(L==R)returnl; intMid=l+r>>1, k2=siz[ls[y]]-Siz[ls[x]]; if(K<=K2)returnquery (LS[Y],LS[X],L,MID,K); returnQuery (rs[y],rs[x],mid+1, r,k-K2);}voidDfsintx) { for(intI=first[x];i;i=Next[i]) {cur++;if(! L[X]) l[x]=cur; Build (Root[cur],root[cur-1],1,100000, Val[i]); } for(intI=first[x];i;i=Next[i]) DFS (to[i]); R[X]=cur;}intMain () {intn=read (); Rep (I,1, N) scanf ("%s", s), insert (s,i); Getfail ();d FS (0); Rep (I,1, N) printf ("%d\n", Query (root[r[pos[i]]],root[l[pos[i]]-1],1,100000, read ())); return 0;}View Code
BZOJ3439:KPM's MC Password