3230: Similar substring
Time limit:20 Sec Memory limit:128 MB
Description
Input
Enter line 1th, which contains 3 integer n,q. Q represents the number of inquiry groups.
Line 2nd is the string s.
Next Q line, two integers i and j per line. (1≤I≤J).
Output
Output a total of Q lines, a number per line represents the answer for each group of queries. If there is no string I or J substring, then output-1.
Sample Input
5 3
Ababa
3 5
5 9
8 10
Sample Output
18
16
-1
HINT
Sample explanation
The 1th group asks: Two substrings are "ABA", "Ababa". F = 32 + 32 = 18.
The 2nd group asks: Two substrings are "Ababa", "Baba". f = 02 + 42 = 16.
Group 3rd asks: there is no 10th substring. Output-1. Data range
n≤100000,q≤100000, the string consists of a lowercase letter ' a ' ~ ' Z '
Solution: The first thing we want to solve is the essentially different substring count problem:
Given that the substring must be prefixed with a suffix, we add each suffix in rank order,
Then each new suffix will produce a new prefix (substring) n-sa+1
But because of the existence of LCP, these substrings and the previous string of repetition of some
so the final formula is σn-sa+1-height, and of course specific details, such as ±1 will be slightly different with the style of the code and the way of calculation, The reader can modify it by itself
And then we thought, the point is, let's just ask for the longest common prefix and the longest public suffix of some two substrings.
So we can run an SA and then reverse the string, we get a suffix array and a weird "prefix array".
Then we find the sub-string corresponding to the endpoint and suffix, and then use RMQ to calculate the LCP interval minimum value can be.
Code implementation (at that time I was transferred to the confusion and then encapsulated 233):
1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespacestd;5typedefLong LongLL;6 Const intn=100010;7 intn,xx[n],yy[n],cnt[n],bin[ at];8 LL Num[n];9 structFleetTen { One intsa[n],height[n],rank[n],f[n][ -]; A CharS[n]; - inti,j,k,p,m; -InlinevoidGet_sa () the { - int*x=xx,*y=yy;m= the; - for(i=0; i<m;++i) cnt[i]=0; - for(i=0; i<n;++i) ++cnt[x[i]=S[i]]; + for(i=1; i<m;++i) cnt[i]+=cnt[i-1]; - for(i=n-1; ~i;--i) sa[--cnt[x[i]]]=i; + for(k=1, p=0;p <n&&k<=n;k<<=1, m=p) A { at for(p=0, I=n-k;i<n;++i) y[p++]=i; - for(i=0; i<n;++i)if(sa[i]>=k) y[p++]=sa[i]-K; - for(i=0; i<m;++i) cnt[i]=0; - for(i=0; i<n;++i) + +Cnt[x[y[i]]; - for(i=1; i<m;++i) cnt[i]+=cnt[i-1]; - for(i=n-1; ~i;--i) sa[--cnt[x[y[i]]]]=Y[i]; in for(Swap (x, y), p=1, x[sa[0]]=0, i=1; i<n;++i) -X[sa[i]]= (y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])? p1:p + +; to } + } -InlinevoidGet_rank () the { * for(i=0; i<n;++i) rank[sa[i]]=i; $ for(k=i=0; i<n;height[rank[i++]]=k)Panax Notoginseng for(k=k?k-1: k,j=sa[rank[i]-1];s[i+k]==s[j+k];++k); - } theInlinevoidST () + { A for(i=0; i<n;++i) f[i][0]=Height[i]; the for(i=1; bin[i]<=n;++i) + for(j=0; j+bin[i]-1<n;++j) -F[j][i]=min (f[j][i-1],f[j+bin[i-1]][i-1]); $ } $Inline LL Query (intLintR) - { - intlen=r-l+1, k=0; the while(bin[k+1]<=len) + +K; - returnMin (f[l][k],f[r-bin[k]+1][k]);Wuyi } theInlinevoidGet_kth (int&st,int&ed,ll RK) - { Wu intAns=lower_bound (NUM,NUM+N,RK)-num; -st=sa[ans],ed=st+height[ans]-1+rk-num[ans-1]; About } $Inlinevoidintn () - {Get_sa (), Get_rank (), ST ();} -InlinevoidCalc () -{ for(i=0; i<n;++i) num[i]=num[i-1]+ll (n-sa[i]-height[i]-1);} A }sfx,pre; + Inline ll get_length (ll Id1,ll id2) the { -Registerinti,j,k,st[2],ed[2]; $Sfx.get_kth (st[0],ed[0],id1); theSfx.get_kth (st[1],ed[1],id2); theLL Val=min (ed[0]+1ll-st[0],ed[1]+1ll-st[1]), tmp=Val; the if(st[0]!=st[1]) the if(sfx.rank[st[0]]<sfx.rank[st[1]]) -Tmp=min (Tmp,sfx.query (sfx.rank[st[0]]+1, sfx.rank[st[1]])); in Else theTmp=min (Tmp,sfx.query (sfx.rank[st[1]]+1, sfx.rank[st[0]])); theed[0]=n-2-ed[0],ed[1]=n-2-ed[1]; About if(ed[0]!=ed[1]) the if(pre.rank[ed[0]]<pre.rank[ed[1]]) theVal=min (Val,pre.query (pre.rank[ed[0]]+1, pre.rank[ed[1]])); the Else +Val=min (Val,pre.query (pre.rank[ed[1]]+1, pre.rank[ed[0]])); - returntmp*tmp+val*Val; the }Bayi intMain () the { theRegisterinti,j,m,a,b,q; LL u,v; -scanf"%d%d%s",&n,&m,sfx.s); - for(bin[0]=i=1; i<= -; ++i) bin[i]=bin[i-1]<<1; the for(i=1; i<=n;++i) pre.s[i-1]=sfx.s[n-i]; thesfx.s[n]=pre.s[n]=1, n++; the Sfx.intn (); PRE.INTN (); Sfx.calc (); the while(m--) - { thescanf"%lld%lld",&u,&v); the if(u>num[n-1]|| v>num[n-1]) printf ("-1\n"); the Elseprintf"%lld\n", Get_length (u,v));94 } the}
[BZOJ3230] Similar string suffix array +rmq