题目描述:给出长度为n的数字串,求两个串,满足:
1.长度相等且大于5;
2.对应项差值相同;
代码:
#include<cstdio> #include<algorithm> using namespace std; #define N 40050 int n,a[N],b[N]; int rank[N],tr[N],hs[N],sa[N],h[N]; bool cmp(int aa,int ab,int k) { if(aa+k>n||ab+k>n)return 0; return rank[aa]==rank[ab]&&rank[aa+k]==rank[ab+k]; } void init() { for(int i=1;i<=n;i++) hs[i]=tr[i]=rank[i]=sa[i]=h[i]=0; } void get_sa() { int i,cnt=0; for(i=1;i<=n;i++)hs[b[i]]++; for(i=1;i<=200;i++)if(hs[i])tr[i]=++cnt; for(i=1;i<=200;i++)hs[i]+=hs[i-1]; for(i=n;i>=1;i--)rank[i]=tr[b[i]],sa[hs[b[i]]--]=i; for(int k=1;cnt!=n;k<<=1) { for(i=1;i<=n;i++)hs[i]=0; for(i=1;i<=n;i++)hs[rank[i]]++; for(i=1;i<=n;i++)hs[i]+=hs[i-1]; for(i=n;i>=1;i--)if(sa[i]>k)tr[sa[i]-k]=hs[rank[sa[i]-k]]--; for(i=1;i<=k;i++)tr[n-i+1]=hs[rank[n-i+1]]--; for(i=1;i<=n;i++)sa[tr[i]]=i; for(i=1,cnt=0;i<=n;i++)tr[sa[i]]=cmp(sa[i-1],sa[i],k)?cnt:++cnt; for(i=1;i<=n;i++)rank[i]=tr[i]; } } void get_h() { for(int i=1;i<=n;i++) { if(rank[i]==1)continue; for(int j=max(h[rank[i-1]]-1,1);;j++) { if(b[i+j-1]==b[sa[rank[i]-1]+j-1])h[rank[i]]=j; else break; } } } bool check(int len) { for(int i=2;i<=n;i++) { if(h[i]<len)continue; for(int j=i-1;j>=2;j--) { if(abs(sa[i]-sa[j])>=len)return 1; if(h[j]<len)break; } } return 0; } int main() { while(scanf("%d",&n)) { if(!n)break; init(); for(int i=1;i<=n;i++) scanf("%d",&a[i]); if(n<10) { printf("0 "); continue; } n--; for(int i=1;i<=n;i++) b[i]=a[i+1]-a[i]+100; get_sa(); get_h(); int l = 0,r = n+1,ans; while(l<=r) { int mid =(l+r)>>1; if(check(mid)) { ans = mid; l=mid+1; }else r=mid-1; } if(ans<4)printf("0 "); else printf("%d ",ans+1); } return 0; }