3230: Similar substring Time limit:20 Sec Memory limit:128 MB
submit:1502 solved:364
[Submit] [Status] [Discuss] Description
Input
Enter line 1th, which contains 3 integer n,q. Q represents the number of inquiries.
Line 2nd is the string s.
Next q row, two integers i and j per line. (1≤I≤J).
Output
The output is a total of q rows, each of which represents the answer to each group of inquiries. If the first or J substring does not exist, then output-1.
Sample Input 5 3
Ababa
3 5
5 9
8 10
Sample Output 18
16
-1
HINT
Sample explanation
1th Group inquiry: Two substring is "ABA", "Ababa". F = 32 + 32 = 18.
2nd Group inquiry: Two substring is "Ababa", "Baba". f = 02 + 42 = 16.
Group 3rd query: no 10th substring exists. Output-1.
Data range
n≤100000,q≤100000, the string consists of only the lowercase letter ' a ' ~ ' Z '
Source
Suffix array + two-point +rmq [submit][status][discuss]
Solving: suffix array + binary +RMQ
Because it is fundamentally different, we can directly get the number of substrings in each position, and then we can find the second answer, which is the suffix of the string ranked K, and the length in the suffix.
Know the ranking, and then RMQ solution can be.
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define N 100003 #
Define M #define LL long using namespace std;
int n,m,len,q,p,st[20][n],l[n];
int sa[n],rank[n],height[n],xx[n],yy[n],*x,*y,a[n],b[n];
int sa1[n],rank1[n],height1[n],st1[20][n];
LL Sum[n];
Char S[n];
struct data{int pos,x; int cmp (int i,int j,int l) {return y[i]==y[j]&& (i+l>len?-1:y[i+l]) = = = (j+l>len?-1:y[j+l);} void Get_sa (
int sa[n],int rank[n],int Height[n],int st[m][n]) {m=200; x=xx; y=yy;
Memset (b,0,sizeof (b));
for (int i=1;i<=len;i++) b[x[i]=a[i]]++;
for (int i=1;i<=m;i++) b[i]+=b[i-1];
for (int i=len;i>=1;i--) sa[b[x[i]]--]=i;
for (int k=1;k<=len;k<<=1) {p = =;
for (int i=len-k+1;i<=len;i++) y[++p]=i;
for (int i=1;i<=len;i++) if (sa[i]>k) y[++p]=sa[i]-k;
for (int i=1;i<=m;i++) b[i]=0;
for (int i=1;i<=len;i++) b[x[y[i]]]++; for (int i=1;i<=m;i++) b[i]+=b[i-1];
for (int i=len;i>=1;i--) sa[b[x[y[i]]]--]=y[i]; Swap (x,y); p=2;
X[sa[1]]=1;
for (int i=2;i<=len;i++) x[sa[i]]=cmp (sa[i-1],sa[i],k)? p-1:p++;
if (P>len) break;
m=p+1;
} = =;
for (int i=1;i<=len;i++) rank[sa[i]]=i;
for (int i=1;i<=len;i++) {if (rank[i]==1) continue;
int j=sa[rank[i]-1];
while (I+p<=len&&j+p<=len&&a[i+p]==a[j+p]) p++;
Height[rank[i]]=p;
P=max (p-1,0);
for (int i=1;i<=len;i++) st[0][i]=height[i]; for (int i=1;i<=17;i++) for (int j=1;j+ (1<<i) -1<=len;j++) st[i][j]=min (st[i-1][j],st[i-1][j+ (1<&
lt; (i-1)]);
int j=0;
for (int i=1;i<=len;i++) {if ((1<< (j+1)) <=i) J + +;
L[i]=j;
} data solve (LL x) {int l=1; int r=len; int ans=0;
while (l<=r) {int mid= (L+R)/2; if (Sum[mid]>=x&& sum[mid-1]<x) {ans=mid;
Break
} if (sum[mid]>x) r=mid-1;
else l=mid+1;
LL T=x-sum[ans-1]; Data A; A.pos=ans;
a.x=height[ans]+ (int) T;
return A;
int calc (int x,int y) {if (x==y) return len;
if (x>y) swap (x,y); int k=l[y-x];
x + +;
return min (st[k][x],st[k][y-(1<<k) +1]);
int Calc1 (int x,int y) {x=rank1[x]; y=rank1[y];
if (x==y) return len;
if (x>y) swap (x,y); int k=l[y-x];
x + +;
return min (st1[k][x],st1[k][y-(1<<k) +1]);
int main () {freopen ("a.in", "R", stdin);
Freopen ("My.out", "w", stdout);
scanf ("%d%d", &len,&q);
scanf ("%s", s+1);
for (int i=1;i<=len;i++) a[i]=s[i]-' a ' +1;
Get_sa (SA,RANK,HEIGHT,ST);
for (int i=1;i<=len;i++) sum[i]= (LL) (Len-sa[i]+1-height[i]);
for (int i=1;i<=len;i++) sum[i]+=sum[i-1];
for (int i=1;i<=len;i++) a[len-i+1]=s[i]-' a ' +1;
Get_sa (SA1,RANK1,HEIGHT1,ST1); for (int i=1;i<=q;i++) {LL x,y; scanf ("%i64d%i64d", &x,&y); if (x>sum[len]| |
Y>sum[len]) {printf (" -1\n");
Continue
} data Ansl=solve (x);
Data ansr=solve (y);
int ll=sa[ansl.pos]+ansl.x-1;
int rr=sa[ansr.pos]+ansr.x-1;
int a=min (min (ansl.x,ansr.x), Calc (ansl.pos,ansr.pos));
int b=min (min (ansl.x,ansr.x), Calc1 (len-ll+1,len-rr+1));
ll ans= (LL) * (LL) + (LL) b* (LL) b;
printf ("%lld\n", ans);
return 0; }