[Background] Topic:
zm liked the bun.
[Title] face Description:
zm every day to buy buns, but in order to lose weight, zm set a series of rules to control the number of buns he bought every day.
He randomly a special string of n, then n string to measure the number of days in the next Q buy buns every day.
Rules are as follows:
1. zm generates two strings day, he called string A string, another string called B string.
2. At this time, each string has a special value F [i], where A is the i-th string special string prefix and suffix B sequence when the i-th string (may overlap), F [i] = 1 otherwise, F [i] = 0.
3. If F [i] is currently equal to 1, then that zm buy the bun. zm every night would do a dream, the dream will be a digital K, zm think this figure unlucky, they wanted him to buy a small number of K buns to zackzh, then I zm wanted to know the number of buns. zm think this problem is too simple for him, then found you, let you on his behalf to write a program to solve this problem.
[Input format:
Enter the file zmchibaozi.in.
The first line contains two numbers n, Q. Next n lines, each line represents a particular string. Next Q rows, each row represents the day A string generated zm, B strings and K.
[Output format]:
Output to a file zmchibaozi.out. Q co rows, each row represents the day numbering K zm buy small buns, -1 is output if no solutions.
[Sample input]:
3 6
aaaaa
Spearheading
bus
a a 1
a aa 2
aa a 2
aaaaa aaaa 1
ABAC Horse 3
ABAC 1
[] Sample output:
1
2
-1
1
-1
2
【data range】:
Represents the total length of a special string s1, s2 denotes the total length of string A, s3 represents the total length of the B string.
For 10% of the data, s1, s2, s3 <= 5000.
There are additional 10% of the data, like all the A string.
There are additional 10% of the data, like all the B string.
There are an additional 30% of the data, each of the A string and B string length is less than 20 and n <= 10000.
To 100% of the data, s1 <= 1000000, s2, s3 <= 2000000, K <= n, m <= 100000, all lowercase string.
[Resolved] title
First of all the special strings can be found on the node position A, B string on these two trie built by two trie tree when positive and negative, so that after each inquiry, the answer is both child nodes of the tree are common K large number of nodes nodes.
Abstract model can continue.
It is between a node in this subtree root of its dfn dfn and dfn + siz-1.
You can get such a problem
FIG x represents a positive trie dfn, y represents the trie anti dfn.
Each string into a specific point (the trie forward dfn, reverse the trie dfn).
Each inquiry will first convert two large K subtrees CCP is a little big point of seeking rectangle K.
It will be transformed into the classic problem of the whole half.
Scanning lines to solve.
code show as below:
#include<bits/stdc++.h> using namespace std; const int N=1e6+5; int n,q,size,ans[N],ge,cnt1,cnt2,sh[N],dq[N],dui[N],cj,cc[N]; struct ztef { int x1,x2,y1,y2,k,id; }a[N<<1],huan2[N]; struct cha { int qi,ho; }b[N],huan[N]; struct line { int he,ze1,ze2,pu,du; }li[N<<1]; string s,ss; struct pigu { int er[N][27],dfn[N],cnt,siz[N]; inline int insert(string x) { int len=x.size(),now=0; for(int i=0;i<len;i++) { if(!er[now][x[i]-'a']) er[now][x[i]-'a']=++cnt; now=er[now][x[i]-'a']; } return now; } inline void dfs(int now) { dfn[now]=++size;siz[now]=1; for(int i=0;i<=25;i++) { if(!er[now][i]) continue; dfs(er[now][i]); siz[now]+=siz[er[now][i]]; } } inline int cha(string x) { int now=0,len=x.size(); for(int i=0;i<len;i++) { if(!er[now][x[i]-'a']) return 0; now=er[now][x[i]-'a']; } return now; } }zh,fa; inline int read() { char c=getchar(); int x=0,f=1; while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();} while(isdigit(c)) {x=(x<<3)+(x<<1)+c-'0';c=getchar();} return x*f; } inline int lowbit(int x) { return x&(-x); } inline void update(int now,int v) { while(now<=cj) { sh[now]+=v; now+=lowbit(now); } } inline int query(int now) { int daan=0; if(now<=0) return 0; while(now) { daan+=sh[now]; now-=lowbit(now); } return daan; } inline bool cmp2(line x,line y) { return x.he<y.he; } inline bool cmp1(cha x,cha y) { return x.qi<y.qi; } inline void solve(int l,int r,int L,int R) { if(L>R) return; if(l==r) { if(r==n+1) for(int i=L;i<=R;i++) ans[dui[i]]=-1; else for(int i=L;i<=R;i++) ans[dui[i]]=l; return; } int cn3=1,mid=(l+r)>>1,cn1=0,cn2=0; for(int i=l;i<=mid;i++) [Huan ++ CN1] = B [I]; Sort (Huan + . 1 , Huan + CN1 + . 1 , CMP1); for ( int I = L; I <= R & lt; I ++ ) { IF (ANS [DUI [I]] == - . 1 ) Continue ; Li [ ++ CN2] = (Line) {A [DUI [I]] X1-. . 1 , A [DUI [I]] Y1, A [DUI [I]] Y2,.. - . 1 , I}; Li [ ++ CN2] = (Line) {A [DUI [I]] X2, A [DUI [I]] Y1, A [DUI [I]] Y2,... . 1 , I }; } Sort (Li + . 1 , Li + CN2 + . 1 , CMP2); for ( int i=1;i<=cn2;i++) { while(cn3<=cn1&&huan[cn3].qi<=li[i].he) { update(huan[cn3].ho,1); cn3++; } dq[li[i].du]+=(query(li[i].ze2)-query(li[i].ze1-1))*li[i].pu; } for(int i=1;i<cn3;i++) update(huan[i].ho,-1); int hu1=L,hu2=R; for(int i=L;i<=R;i++) { if(dq[i]>=a[dui[i]].k) cc[hu1++]=dui[i]; else { cc[hu2--]=dui[i]; a[dui[i]].k-=dq[i]; } dq[i]=0; } for(int i=L;i<=R;i++) dui[i]=cc[i]; solve(l,mid,L,hu1-1); solve(mid+1,r,hu2+1,R); } int main() { n=read();q=read(); for(int i=1;i<=n;i++) { cin>>s; b[i].qi=zh.insert(s); reverse(s.begin(),s.end()); b[i].ho=fa.insert(s); } zh.dfs(0);size=0;fa.dfs(0); for(int i=1;i<=n;i++) { b[i].qi=zh.dfn[b[i].qi]; b[i].ho=fa.dfn[b[i].ho]; } cj=fa.cnt+1; for(int i=1,x,y,z;i<=q;i++) { cin>>s>>ss>>z; dui[i]=i; reverse(ss.begin(),ss.end()); x=zh.cha(s); y=fa.cha(ss);a[i].k=z; if(x==0||y==0) {ans[i]=-1;continue;} a[i].id=i; a[i].x1=zh.dfn[x];a[i].x2=zh.dfn[x]+zh.siz[x]-1; a[i].y1=fa.dfn[y];a[i].y2=fa.dfn[y]+fa.siz[y]-1; } solve(1,n+1,1,q); for(int i=1;i<=q;i++) cout<<ans[i]<<"\n"; return 0; }