4556: [tjoi2016&heoi2016] string time limit:20 Sec Memory limit:128 MB
submit:169 solved:87
[Submit] [Status] [Discuss] Description's sister's birthday, her little friend bought a birthday gift from some east. Birthday presents in a magical box. Outside the box was written a string s of N, and M questions. Good sister must answer this question correctly, in order to open the box to get gifts, promotion, as CEO, married Gaofu, embark on the pinnacle of life. Each problem has a,b,c,d four parameters, ask you substring s[a. b] for all substrings and s[c. What is the maximum length of the longest public prefix for d]? My sister is not good at doing such a problem, so she asked you for help, how can you assist her? The first line of input inputs has two positive integer n,m, each representing the length of the string and the number of queries. The next line is a string of n long. Next m line, each line has 4 number a,b,c,d, indicates asks S[a. b] for all substrings and s[c. The maximum value of the longest public prefix for d]. 1<=n,m<=100,000, string with only lowercase English letters, a<=b,c<=d,1<=a,b,c,d<=n Output
For each query, output the answer.
Sample Input5 5
Aaaaa
1 1 1 5
1 5 1 1
2 3 2 3
2 4 2 3
2 3 2 4Sample Output1
1
2
2
2 hint source : Suffix array I think of a method that is not online ... First, use the suffix array first to get out height[] and sa[]. Then for a group of queries s[a. b] for all substrings and s[c. d] prefix , we can put s[c. D] Located in the suffix array, i.e. rank[]. Then can think of if s[a. b] substring and s[c. D] is equal to the prefix, then for a s[a. b] A substring beginning with a suffix, must and s[c. D] The suffix has a public prefix, that is, two strings subscript the middle part of the height[] are not 0. Example: Original string: Ababa inquiry: (a,b,c,d) = (3,4,1,5) suffix after sorting: note: sa[] all + 1, height[] is the public prefix length for the current suffix and the previous suffix. Sa[] height[] 5 0 a 3 1 a b a 1 3 &N Bsp;a b A B a 4 0 b a 2 &NBS P 2 b a B a we'll find s[c first. D] The suffix beginning with the string: A B A B A and then to the back and forth (here is only an illustration of the forward extension): 1. The prefix of a b A and a B A is 3, and Sa[i-1] is 3, so it can be extended forward, and the length is updated to 2 (because S[a: b] In A is 3,b 4, so it cannot be updated to 3, or the [a, b] range is exceeded). 2. a b A and A are prefixed with 1, but Sa[i-1] is 5, not [A, b] is the [3,4] range, so the beginning is not in the tube (but also to extend forward). 3. The head is gone, there is no previous one, so stop. Note 1: Stop condition one for the head, there is also a maximum length of the current update for height[i]< (because it can be thought that the length of the forward and backward extension has been monotonous, so it can quickly become 0) Note 2: The maximum length of every update is not beyond the range, that is, to be less than ( d-c+1) and (b-sa[i]+1), Sa[i] is the starting position of the string for the current extension.
Note 3 (the most important one): Because of the way forward expansion, such as to the first bit, but we in this bit of length is not necessarily height[i], but from the initial expansion of the position to the first bit of the height[] the minimum!!! Like the example above, the public prefix for b A and b A and b A is not 3, nor is it 2, but the smallest height[in the middle of the two strings], which is 0. Scale backwards. And then there's no more ... This allows you to run very fast, as there is not too much forward and backward expansion. So complexity is almost the complexity of the suffix array ... Then the Bzoj to the first ... 972ms ... More than 4 times times faster than the second place ... Myself to a few sets of good data found in the shoot: In:5 1abaaa4 5 1 4 out:1 in:
9 1
Baabbbbab
2 5 7 9
Out
1
In
5 1
Aaaab
2 3 4 5
Out
1
1#include <bits/stdc++.h>2 using namespacestd;3 #defineMAXN 1000104 #defineINF 1e95 intWS[MAXN],WA[MAXN],WB[MAXN],SA[MAXN],WV[MAXN],RANK[MAXN],HEIGHT[MAXN];6 CharSTR[MAXN];7 intRead ()8 {9 ints=0, fh=1;CharCh=GetChar ();Ten while(ch<'0'|| Ch>'9'){if(ch=='-') fh=-1; ch=GetChar ();} One while(ch>='0'&&ch<='9') {s=s*Ten+ (ch-'0'); ch=GetChar ();} A returns*fh; - } - intcmpint*r,intAintBintL) {return(R[a]==r[b]) && (r[a+l]==r[b+l]);} the voidDA (Char*r,int*sa,intNintm) - { - inti,j,p,*x=wa,*y=wb,*T; - for(i=0; i<m;i++) ws[i]=0; + for(i=0; i<n;i++) ws[x[i]=r[i]]++; - for(i=0; i<m;i++) ws[i]+=ws[i-1]; + for(i=n-1; i>=0; i--) sa[--ws[x[i]]]=i; A for(j=1, p=1;p <n;j*=2, m=p) at { - for(p=0, i=n-j;i<n;i++) y[p++]=i; - for(i=0; i<n;i++)if(SA[I]>=J) y[p++]=sa[i]-J; - for(i=0; i<n;i++) wv[i]=X[y[i]]; - for(i=0; i<m;i++) ws[i]=0; - for(i=0; i<n;i++) ws[wv[i]]++; in for(i=0; i<m;i++) ws[i]+=ws[i-1]; - for(i=n-1; i>=0; i--) sa[--ws[wv[i]]]=Y[i]; to for(t=x,x=y,y=t,p=1, x[sa[0]]=0, i=1; i<n;i++) +X[SA[I]]=CMP (y,sa[i-1],sa[i],j)? p1:p + +; - } the } * voidCalheight (intN) $ {Panax Notoginseng inti,j,k=0; - for(i=1; i<=n;i++) rank[sa[i]]=i; the for(i=0; i<n;height[rank[i++]]=k) + for(k?k--:0, j=sa[rank[i]-1];str[i+k]==str[j+k];k++); A } the intSolve (intS1,intS2,intS3,intS4,intN) + { - intlen=0, wz,i,len=INF; $wz=rank[s3-1];//len=s4-s3+1; $ if(SA[WZ]>=S1&&SA[WZ]<=S2) Len=max (Len,min (s4-s3+1, s2-sa[wz]+1)); - for(i=wz;i>=2; i--) - { the if(height[i]==0|| Height[i]<=len) Break; - if(sa[i-1]>=s1&&sa[i-1]<=S2)Wuyi { theLen=max (Len,min (min (len,height[i)), s2-sa[i-1]+1), s4-s3+1)); - //len=min (Len,len); Wu } -len=min (len,height[i]); About } $len=INF; - for(i=wz+1; i<=n;i++) - { - if(height[i]==0|| Height[i]<=len) Break; A if(sa[i]>=s1&&sa[i]<=S2) + { theLen=max (Len,min (min (len,height[i)), s2-sa[i]+1), s4-s3+1)); - //len=min (Len,len); $ } thelen=min (len,height[i]); the } the returnLen; the } - intMain () in { theFreopen ("heoi2016_str.in","R", stdin); theFreopen ("Heoi2016_str.out","W", stdout); About intN,m,lstr,i,s1,s2,s3,s4; theN=read (); m=read (); thescanf"\n%s", str); theLstr=strlen (str); +str[lstr+1]=0; -DA (str,sa,lstr+1, the); the calheight (LSTR);Bayi for(i=1; i<=n;i++) sa[i]++; the for(i=1; i<=m;i++) the { -S1=read (); S2=read (); S3=read (); s4=read (); -printf"%d\n", Solve (s1,s2,s3,s4,n)); the } the fclose (stdin); the fclose (stdout); the return 0; -}
Bzoj4556: [tjoi2016&heoi2016] string suffix array