后缀数组,暴力硬跑
贼快
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #define MAXN 100005 7 using namespace std; 8 int buc[MAXN],wa[MAXN],wb[MAXN]; 9 int r[MAXN],sa[MAXN],rank[MAXN],height[MAXN]; 10 void getheight(int n){ 11 int i,j,k=0; 12 for(i=0;i<n;i++)rank[sa[i]]=i; 13 for(i=0;i<n;height[rank[i++]]=k) 14 for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); 15 return ; 16 } 17 bool cmp(int *c,int a,int b,int d) 18 {return c[a]==c[b]&&c[a+d]==c[b+d];} 19 void da(int n,int m=130){ 20 int i,j,p,*x=wa,*y=wb,*t; 21 for(i=0;i<m;i++)buc[i]=0; 22 for(i=0;i<n;i++)buc[x[i]=r[i]]++; 23 for(i=1;i<m;i++)buc[i]+=buc[i-1]; 24 for(i=n-1;~i;i--)sa[--buc[x[i]]]=i; 25 for(j=1,p=1;p<n;j*=2,m=p){ 26 for(i=n-j,p=0;i<n;i++)y[p++]=i; 27 for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j; 28 for(i=0;i<m;i++)buc[i]=0; 29 for(i=0;i<n;i++)buc[x[y[i]]]++; 30 for(i=1;i<m;i++)buc[i]+=buc[i-1]; 31 for(i=n-1;~i;i--)sa[--buc[x[y[i]]]]=y[i]; 32 for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) 33 x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; 34 } 35 getheight(n); 36 return ; 37 } 38 int n,q; 39 char s[MAXN]; 40 int main(){ 41 scanf("%d%d",&n,&q); 42 scanf("%s",s); 43 for(int i=0;i<n;i++)r[i]=s[i]; 44 da(n+1); 45 int ans,minn,pos,now,a,b,c,d; 46 while(q--){ 47 scanf("%d%d%d%d",&a,&b,&c,&d); 48 a--;b--;c--;d--; 49 ans=0; minn=min(d-c+1,b-a+1); 50 pos=rank[c]; 51 if(sa[pos]>=a&&sa[pos]<=b)ans=max(ans,min(minn,min(b-sa[pos]+1,d-c+1))); 52 minn=min(minn,height[pos]); 53 for(int i=pos-1;i>=0;i--){ 54 if(minn<=ans)break; 55 now=sa[i]; 56 if(now>=a&&now<=b)ans=max(ans,min(minn,min(b-sa[i]+1,d-c+1))); 57 minn=min(minn,height[i]); 58 } 59 minn=min(d-c+1,b-a+1); 60 for(int i=pos+1;i<=n;i++){ 61 minn=min(minn,height[i]); 62 if(minn<=ans)break; 63 now=sa[i]; 64 if(now>=a&&now<=b){ans=max(ans,min(minn,min(b-sa[i]+1,d-c+1)));} 65 } 66 printf("%d\n",ans); 67 } 68 return 0; 69 }