出题人在下面写题解系列
本质不同的字串个数=∑n-h[i]-sa[i]
然后一个一个套就好了
#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn 200021
#define LL long long
using namespace std;
struct SA{
int n,sa[maxn],rk[maxn],f[maxn*2][18],t1[maxn],t2[maxn];
int h[maxn],lg[maxn],cnt[maxn];
LL sum[maxn];
char s[maxn];
void build(int m){
int p,i,*x=t1,*y=t2;
for(i=0;i<n;i++)cnt[x[i]=s[i]-'a']++;
for(i=1;i<m;i++)cnt[i]+=cnt[i-1];
for(i=n-1;i>=0;i--)sa[--cnt[x[i]]]=i;
for(int k=1;k<n;k<<=1){
p=0;
for(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>=0;i--)sa[--cnt[x[y[i]]]]=y[i];
swap(x,y);
p=1,x[sa[0]]=0;
for(i=1;i<n;i++)
x[sa[i]]= sa[i-1]+k<n&&sa[i]+k<n&&y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k] ?
p-1 : p++;
if(p>=n)break;
m=p;
}
}
void get_h(){
for(int i=2;i<=n;i++)lg[i]=lg[i>>1]+1;
for(int i=0;i<n;i++)rk[sa[i]]=i;
for(int k=0,i=0;i<n;i++){
if(k>=1)k--;
if(rk[i]==0)continue;
int x=sa[rk[i]-1];
while(s[x+k]==s[i+k])k++;
h[rk[i]]=k;
}
memset(f,127,sizeof(f));
for(int i=0;i<n;i++)f[i][0]=h[i];
for(int i=1;i<=17;i++){
for(int j=0;j<n;j++){
f[j][i]=min(f[j][i-1],f[j+(1<<i-1)][i-1]);
}
}
for(int i=0;i<n;i++)sum[i]=sum[i-1]+n-sa[i]-h[i];
}
int getk(LL k){
int l=0,r=n-1;
while(l<r){
int mid=l+r>>1;
if(sum[mid]>=k)r=mid;
else l=mid+1;
}
return l;
}
int rmq(int a,int b){
a=rk[a],b=rk[b];
if(a>b)swap(a,b);
if(a==b)return n-sa[a];
a++;
int len=lg[b-a+1];
return min(f[a][len],f[b-(1<<len)+1][len]);
}
}A,B;
int n,Q;
char s[maxn];
void solve(LL a,LL b){
int la,ra,lb,rb,pa,pb,x,y;
if(a>b)swap(a,b);
if(b>A.sum[n-1]){puts("-1");return;}
pa=A.getk(a),pb=A.getk(b);
la=A.sa[pa],lb=A.sa[pb];
ra=a-(pa==0 ? 0 : A.sum[pa-1]) + A.sa[pa] + A.h[pa] - 1;
rb=b-(pb==0 ? 0 : A.sum[pb-1]) + A.sa[pb] + A.h[pb] - 1;
x=A.rmq(la,lb),x=min(x,min(ra-la+1,rb-lb+1));
y=B.rmq(n-rb-1,n-ra-1),y=min(y,min(ra-la+1,rb-lb+1));
printf("%lld\n",(LL)x*x+(LL)y*y);
}
int main(){
scanf("%d%d%s",&n,&Q,s);
A.n=B.n=n;
for(int i=0;i<n;i++)A.s[i]=B.s[n-i-1]=s[i];
A.build(220);B.build(220);
A.get_h();
B.get_h();
LL a,b;
while(Q--){
scanf("%lld%lld",&a,&b);
solve(a,b);
}
return 0;
}