bzoj1717 [Usaco2006 Dec]Milk Patterns 产奶的模式

先求后缀数组、相邻两个后缀的最长公共前缀

二分答案,o(n)check

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<string>
  7 #include<cmath>
  8 #include<ctime>
  9 #include<queue>
 10 #include<stack>
 11 #include<map>
 12 #include<set>
 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
 14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
 15 #define Clear(a,b) memset(a,b,sizeof(a))
 16 #define inout(x) printf("%d",(x))
 17 #define douin(x) scanf("%lf",&x)
 18 #define strin(x) scanf("%s",(x))
 19 #define LLin(x) scanf("%lld",&x)
 20 #define op operator
 21 #define CSC main
 22 typedef unsigned long long ULL;
 23 typedef const int cint;
 24 typedef long long LL;
 25 using namespace std;
 26 void inin(int &ret)
 27 {
 28     ret=0;int f=0;char ch=getchar();
 29     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
 30     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
 31     ret=f?-ret:ret;
 32 }
 33 int n,s[100010],t[100010],t2[100010],c[1000010],sa[100010];
 34 void build_sa(int m)
 35 {
 36     int *x=t,*y=t2,p=0;
 37     re(i,0,n-1)x[i]=s[i],c[x[i]]++;
 38     re(i,1,m-1)c[i]+=c[i-1];
 39     rre(i,n-1,0)sa[--c[x[i]]]=i;
 40     for(int k=1;k<=n;k<<=1)
 41     {
 42         rre(i,n-1,n-k)y[++p]=i;
 43         re(i,0,n-1)if(sa[i]>k)y[p++]=sa[i]-k;
 44         Clear(c,0);
 45         re(i,0,n-1)c[x[y[i]]]++;
 46         re(i,1,m-1)c[i]+=c[i-1];
 47         rre(i,n-1,0)sa[--c[x[y[i]]]]=i;
 48         swap(x,y);p=1;
 49         re(i,1,n-1)x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]]==y[sa[i]-1]?p-1:p++;
 50         if(p>=n)break;
 51         m=p;
 52     }
 53     return ;
 54 }
 55 int height[100010];
 56 void build_height()
 57 {
 58     static int rank[100010];
 59     re(i,0,n-1)rank[sa[i]]=i;
 60     height[rank[0]]=0;
 61     int k=0; 
 62     re(i,0,n-1)
 63     {
 64         if(k)k--;
 65         if(!rank[i])continue;
 66         int j=sa[rank[i]-1];
 67         while(s[i+k]==s[j+k])k++;
 68         height[rank[i]]=k;
 69     }
 70 }
 71 bool check(int k)
 72 {
 73     int shu=0;
 74     re(i,1,n-1)
 75     {
 76         if(height[i]>=k)shu++;
 77         else 
 78         {
 79             if(shu+1>=k)return 1;
 80             shu=0;
 81         }
 82     }
 83     if(shu+1>=k)return 1;
 84     return 0;
 85 }
 86 int main()
 87 {
 88     inin(n);
 89     re(i,0,n-1)inin(s[i]);
 90     build_sa(1000000);
 91     build_height();
 92     int l=0,r=n+1;
 93     while(l<r-1)
 94     {
 95         int mid=(l+r)>>1;
 96         if(check(mid))l=mid;
 97         else r=mid;
 98     }
 99     cout<<l;
100      return 0;
101 }

 

posted @ 2016-02-28 08:56  HugeGun  阅读(469)  评论(0编辑  收藏  举报