This problem is also up from the white paper.
Portal: https: //vjudge.net/problem/POJ-3729
Meaning of the questions: to give you a, b string, so you find a string has a maximum length of the string of all common prefix number suffix suffix and b equal to k.
Reference: https: //blog.csdn.net/lj94093/article/details/44703723
In fact, this question there are a few to say.
1, suffix array of conventional practice, the two strings with a special character all together, then this topic and the number may be zero, so to manually +1, 0 do not know why it is not. . .
2, the common prefix length b is equal to the maximum k is converted into NUM (maximum value> = k) -num (maximum value> = k + 1). Such conversion what use is it? The maximum value of> = k, which is a suffix to meet me with a suffix of b> = k can be counted.
3, the specific code is visible, look at the code to understand. We array less than k h h the array is divided into several sections, imagine, in the same paragraph, h is> = k, then if we have a sequence b in this paragraph, then all this paragraph a string are satisfied> = k it, because you can have a meet.
4, Article 3 of analysis is only a rough analysis, little details, and the details do suffix array problem often encountered is that h (in fact, online array of height) meaning an array of records, so that the maximum i and j are common prefix length h [i + 1] to h [j]. That is, the left and right to open and close. It is added in this paragraph i to j h are greater than or equal to k, we have a look at the i-1 that case, although the h [i -1] <k. Do not forget the first one. Then swept past has been encountered h <k's updated look.
Loved by the code.
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 typedef long long ll; 5 const int N=100000+9; 6 int s[N],rnk[N],sa[N],h[N],t[N],t2[N],c[N]; 7 void get_sa(int n,int m){ 8 int *x=t,*y=t2; 9 for(int i=0;i<m;++i) c[i]=0; 10 for(int i=0;i<n;++i) ++c[x[i]=s[i]]; 11 for(int i=1;i<m;++i) c[i]+=c[i-1]; 12 for(int i=n-1;i>=0;--i) sa[--c[x[i]]]=i; 13 for(int k=1;k<=n;k<<=1){ 14 int p=0; 15 for(int i=n-k;i<n;++i) y[p++]=i; 16 for(int i=0;i<n;++i) if(sa[i]-k>=0) y[p++]=sa[i]-k; 17 for(int i=0;i<m;++i) c[i]=0; 18 for(int i=0;i<n;++i) ++c[x[y[i]]]; 19 for(int i=1;i<m;++i) c[i]+=c[i-1]; 20 for(int i=n-1;i>=0;--i) sa[--c[x[y[i]]]]=y[i]; 21 swap(x,y); 22 p=1;x[sa[0]]=0; 23 for(int i=1;i<n;++i) x[sa[i]]=(y[sa[i-1]]==y[sa[i]] && y[sa[i]+k]==y[sa[i-1]+k])?p-1:p++; 24 if(p>=n) break; 25 m=p; 26 } 27 } 28 void get_h(int n){ 29 for(int i=0;i<n;++i) rnk[sa[i]]=i; 30 int k=0; 31 for(int i=0;i<n;++i){ 32 if(k) --k; 33 if(rnk[i]==0){ 34 k=0; 35 continue; 36 } 37 int j=sa[rnk[i]-1]; 38 while(s[i+k]==s[j+k]) ++k; 39 h[rnk[i]]=k; 40 } 41 } 42 ll solve(int k,int n,int l1){ 43 ll ans=0; 44 int a=0; 45 bool b=0; 46 if(sa[0]<l1) ++a; 47 if(sa[0]>l1) b=1; 48 for(int i=1;i<n;++i){ 49 if(h[i]>=k){ 50 if(sa[i]<l1) ++a; 51 if(sa[i]>l1) b=1; 52 } 53 else{ 54 if(b) ans+=a; 55 a=b=0; 56 if(sa[i]<l1) ++a; 57 if(sa[i]>l1) b=1; 58 } 59 } 60 return ans; 61 } 62 int main(){ 63 int n,m,k; 64 while(~scanf("%d %d %d",&n,&m,&k)){ 65 for(int i=0;i<n;++i){ 66 scanf("%d",&s[i]); 67 ++s[i]; 68 } 69 s[n]=10000+7; 70 for(int i=n+1;i<n+1+m;++i){ 71 scanf("%d",&s[i]); 72 ++s[i]; 73 } 74 get_sa(n+m+1,10000+8); 75 get_h(n+m+1); 76 printf("%lld\n",solve(k,n+m+1,n)-solve(k+1,n+m+1,n)); 77 } 78 return 0; 79 }
emm online and does not know why the last fill in a 0. str, then the ranking becomes 0 to n a. . . . . . Because my idea is as close as possible to the template, that is, what are the rnk and sa 0 to n-1, then it will not make the final str 0, because it feels like a good control of the border. . . .