Substring 题解
\color{purple}\mathrm{Substring} 题解
subtask 1:
当
subtask 2:
直接暴力枚举即可。
subtask 3:
对于每个询问,我们将
subtask 4:
当
定义
subtask 5:
subtask 4 已经很接近正解了,只需将
AC Code
#include<iostream>
#include<cstdio>
using namespace std;
int p=1,Q,n,len,ans,bl[1000005],sa[2][1000005],rk[2][1000005],v[1000005],f[1000005],g[20][1000005],logg[1000005];
string s,t,a;
inline void read(int &x) {
x=0;int f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
x*=f;
}
inline void mul(int *sa,int *rk,int *SA,int *RK,int n,int k) {
for(int i=1;i<=n;i++)v[rk[sa[i]]]=i;
for(int i=n;i>=1;i--)if(sa[i]>k)SA[v[rk[sa[i]-k]]--]=sa[i]-k;
for(int i=n-k+1;i<=n;i++)SA[v[rk[i]]--]=i;
for(int i=1;i<=n;i++)RK[SA[i]]=RK[SA[i-1]]+(rk[SA[i]]!=rk[SA[i-1]]||rk[SA[i]+k]!=rk[SA[i-1]+k]);
}
inline void pre() {
for(int i=1;i<=n;i++)v[a[i]]++;
for(int i=1;i<=130;i++)v[i]+=v[i-1];
for(int i=1;i<=n;i++)sa[p][v[a[i]]--]=i;
for(int i=1;i<=n;i++)rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]);
for(int i=1;i<n;i<<=1,p^=1)mul(sa[p],rk[p],sa[p^1],rk[p^1],n,i);
for(int i=1,k=0;i<=n;i++) {
int j=sa[p][rk[p][i]-1];
while(a[i+k]==a[j+k])k++;
f[rk[p][i]]=k;
if(k)k--;
}
}
inline void st() {
for(int i=1;1<<i<=n;i++)
for(int j=1;j<=n-(1<<i)+1;j++)
g[i][j]=max(g[i-1][j],g[i-1][j+(1<<i-1)]);
}
inline int ask(int l,int r) {
if(l>r)swap(l,r);
int k=logg[r-l+1];
return max(g[k][l],g[k][r-(1<<k)+1]);
}
inline int solve(int ql,int qr) {
ql+=len+1,qr+=len+1;
int l=0,r=qr-ql+1,ans=0,mid;
while(l<=r) {
mid=l+r>>1;
if(ask(ql,qr-mid+1)>=mid)l=mid+1,ans=mid;
else r=mid-1;
}
return ans;
}
signed main() {
cin>>s>>t;
read(Q);
len=s.size();
a=' '+s+'#'+t,n=a.size()-1;
for(int i=2;i<=n;i++) {
logg[i]=logg[i-1];
if((1<<logg[i]+1)<=i)logg[i]++;
}
for(int i=1;i<=len;i++)bl[i]=1;
for(int i=len+2;i<=n;i++)bl[i]=2;
pre();
int minn=0x7fffffff;
for(int i=1;i<=n;i++) {
if(!bl[sa[p][i]])continue;
if(bl[sa[p][i]]==2) {
minn=min(minn,f[i]);
g[0][sa[p][i]]=minn;
}else minn=0x7fffffff;
}
minn=0;
for(int i=n;i>=1;i--) {
if(!bl[sa[p][i]])continue;
if(bl[sa[p][i]]==2)g[0][sa[p][i]]=max(g[0][sa[p][i]],minn);
else minn=0x7fffffff;
minn=min(minn,f[i]);
}
st();
while(Q--) {
int l,r;
read(l),read(r);
printf("%d\n",solve(l,r));
}
return 0;
}
验题大佬 leihonglongyin 似乎有