题目大意:
给你n个串(s_1sim s_n),要你在每个串中找一个长度为k的子串,满足任意(1leqslant i<k),有(s_1[i+1]-s_1[i]=s_2[i+1]-s_2[i]=dots=s_n[i+1]-s_n[i])。问满足条件的k最大是多少。
解题思路:
相邻两个数差相等,我们先将原串进行差分。
然后首尾相连求后缀数组(中间用分隔符隔开)。
二分答案。对于答案t,考虑height数组中所有连续的,且大于等于t的子区间,若包含1~n所有串,则答案可行。
由于进行了差分,最后答案+1即可。
C++ Code:
#include<bits/stdc++.h> const int NN=1200005; inline int readint(){ int c=getchar(),d=0,f=0; for(;!isdigit(c);c=getchar())f=c=='-'; for(;isdigit(c);c=getchar()) d=(d<<3)+(d<<1)+(c^'0'); return f?-d:d; } int N,s[NN],n=0,a[1005],fg=30005,t1[NN],t2[NN],c[NN],rk[NN],height[NN],belong[NN],sa[NN]; bool vis[1005]; inline void sa_sort(){ int*x=t1,*y=t2,m=60000; memset(c,0,sizeof c); for(int i=1;i<=n;++i)++c[x[i]=s[i]]; for(int i=1;i<=m;++i)c[i]+=c[i-1]; for(int i=n;i;--i)sa[c[x[i]]--]=i; for(int k=1;k<=n;k<<=1){ int p=0; for(int i=n-k+1;i<=n;++i)y[++p]=i; for(int i=1;i<=n;++i)if(sa[i]>k)y[++p]=sa[i]-k; for(int i=0;i<=m;++i)c[i]=0; for(int i=1;i<=n;++i)++c[x[y[i]]]; for(int i=1;i<=m;++i)c[i]+=c[i-1]; for(int i=n;i;--i)sa[c[x[y[i]]]--]=y[i]; int*tmp=x;x=y,y=tmp; x[sa[p=1]]=1; for(int i=2;i<=n;++i) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p:++p; if(p==n)break; m=p; } } inline void get_height(){ for(int i=1;i<=n;++i)rk[sa[i]]=i; for(int i=1,k=0;i<=n;++i) if(rk[i]!=1){ if(k)--k; int j=sa[rk[i]-1]; while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k])++k; height[rk[i]]=k; } } inline bool check(int k){ memset(vis,0,sizeof vis); int ok=1; vis[belong[sa[1]]]=1; for(int i=2;i<=n;++i){ if(height[i]>=k){ if(!vis[belong[sa[i]]]){ vis[belong[sa[i]]]=1; if(++ok>=N)return 1; } }else{ int j; for(j=i-1;j&&height[j]>=k;--j) vis[belong[sa[j]]]=0; vis[belong[sa[j]]]=0; vis[belong[sa[i]]]=1; ok=1; } if(!belong[sa[i]])break; } return 0; } int main(){ N=readint(); for(int i=1;i<=N;++i){ int nn=readint(); for(int j=0;j<nn;++j)a[j]=readint(); for(int j=nn-1;j;--j)a[j]-=a[j-1]; for(int j=1;j<nn;++j)s[++n]=a[j]+10001,belong[n]=i; s[++n]=fg++; } sa_sort(); get_height(); int l=1,r=1001,ans=0; while(l<=r){ int mid=l+r>>1; if(check(mid))l=(ans=mid)+1;else r=mid-1; } printf("%d ",ans+1); return 0; }