zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    线性表——(2)单向链表
    线性表——(1)顺序表
    UVa 1592 数据库
    UVa 12096 集合栈计算机
    Python 协程
    Python 多线程及进程
    Python 日志(Log)
    Python 函数式编程
    Python基础
    DB2 获取前两天的数据
  • 原文地址:https://www.cnblogs.com/HugeGun/p/5224051.html
Copyright © 2011-2022 走看看