Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 16365 | Accepted: 5636 |
Description
Input
Output
Sample Input
30 25 27 30 34 39 45 52 60 69 79 69 60 52 45 39 34 30 26 22 18 82 78 74 70 66 67 64 60 65 80 0
Sample Output
5 后缀数组简单应用,求出sa,rank,height数组,然后二分答案,判断可行性。 代码:/* *********************************************** Author :xianxingwuguan Created Time :2014-1-27 10:57:50 File Name :1.cpp ************************************************ */ #pragma comment(linker, "/STACK:102400000,102400000") #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std; const int maxn=600010; /* * sa 数组: 排第几的是谁 * rank数组:谁排第几。 * height[i]:sa[i],sa[i-1]的最长公共前缀。 * */ int str[maxn],sa[maxn],rank[maxn],height[maxn],t1[maxn],t2[maxn],c[maxn]; void da(int *str,int n,int m) { int i,j,k,p,*x=t1,*y=t2; for(i=0;i<m;i++)c[i]=0; for(i=0;i<n;i++)c[x[i]=str[i]]++; for(i=1;i<m;i++)c[i]+=c[i-1]; for(i=n-1;i>=0;i--)sa[--c[x[i]]]=i; for(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++)c[i]=0; for(i=0;i<n;i++)c[x[y[i]]]++; for(i=1;i<m;i++)c[i]+=c[i-1]; for(i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i]; swap(x,y); x[sa[0]]=0; p=1; for(i=1;i<n;i++) x[sa[i]]=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 calheight(int *str,int n) { int i,j,k=0; for(i=0;i<=n;i++)rank[sa[i]]=i; for(i=0;i<n;i++) { if(k)k--; j=sa[rank[i]-1]; while(str[i+k]==str[j+k])k++; height[rank[i]]=k; } } bool judge(int *sa,int n,int k) { int i,mx=sa[1],mn=sa[1]; for(i=2;i<=n;i++) { if(height[i]<k)mx=mn=sa[i]; else { if(sa[i]<mn)mn=sa[i]; if(sa[i]>mx)mx=sa[i]; if(mx-mn>k)return 1; } } return 0; } int main() { //freopen("data.in","r",stdin); //freopen("data.out","w",stdout); int i,j,k,m,n; while(~scanf("%d",&n)&&n) { scanf("%d",&j); for(i=0;i<n-1;i++) { scanf("%d",&k); str[i]=k-j+100; j=k; } str[n-1]=0; da(str,n,200); calheight(str,n-1); int l=1,r=n/2; while(l<r) { m=(l+r+1)>>1; if(!judge(sa,n-1,m))r=m-1; else l=m; } if(l>=4)l++;else l=0; printf("%d\n",l); } return 0; }
原文:http://blog.csdn.net/xianxingwuguan1/article/details/18817313