zoukankan      html  css  js  c++  java
  • poj_3261_Milk Patterns(后缀数组)

    题目链接:poj_3261_Milk Patterns

    题意:

    给你一串数,让你找重复出现不少于k次的子串的最长长度,重复出现可重叠

    题解:

    老套路,还是二分答案,然后用height数组来check答案

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define F(i,a,b) for(int i=a;i<=b;i++)
     4 using namespace std;
     5 
     6 namespace suffixarray{    
     7     #define FN(n) for(int i=0;i<n;i++)
     8     const int N =2E5+7;
     9     int rnk[N],sa[N],height[N],c[N],s[N];
    10     void getsa(int n,int m,int *x=rnk,int *y=height){
    11         FN(m)c[i]=0;FN(n)c[x[i]=s[i]]++;FN(m)c[i+1]+=c[i];
    12         for(int i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
    13         for(int k=1,p;p=0,k<=n;k=p>=n?N:k<<1,m=p){
    14             for(int i=n-k;i<n;i++)y[p++]=i;
    15             FN(n)if(sa[i]>=k)y[p++]=sa[i]-k;
    16             FN(m)c[i]=0;FN(n)c[x[y[i]]]++;FN(m)c[i+1]+=c[i];
    17             for(int i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
    18             swap(x,y),p=1,x[sa[0]]=0;
    19             for(int i=1;i<n;i++)
    20             x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
    21         }
    22         FN(n)rnk[sa[i]]=i;
    23         for(int i=0,j,k=0;i<n-1;height[rnk[i++]]=k)
    24         for(k=k?k-1:k,j=sa[rnk[i]-1];s[i+k]==s[j+k];k++);
    25     }
    26 }
    27 using namespace suffixarray;
    28 int n,k,a[N],ed;
    29 
    30 inline int getid(int x){return lower_bound(a+1,a+1+ed,x)-a;}
    31 
    32 bool check(int x,int cnt=1)
    33 {
    34     F(i,2,n)if(height[i]>=x){if(++cnt>=k)return 1;}else cnt=1;
    35     return 0;
    36 }
    37 
    38 int main()
    39 {
    40     while(~scanf("%d%d",&n,&k))
    41     {
    42         F(i,1,n)scanf("%d",a+i),s[i-1]=a[i];
    43         sort(a+1,a+1+n),ed=1;
    44         F(i,2,n)if(a[i]!=a[ed])a[++ed]=a[i];
    45         F(i,0,n-1)s[i]=getid(s[i]);
    46         s[n]=0,getsa(n+1,ed+1);
    47         int l=1,r=n,mid,ans=0;
    48         while(l<=r)mid=(l+r)>>1,check(mid)?l=(ans=mid)+1:r=mid-1;
    49         printf("%d
    ",ans);
    50     }
    51     return 0;
    52 }
    View Code
  • 相关阅读:
    vb笔记
    linux学习笔记
    linnux--shell
    # 用类来封装动态数组:分文件编写
    面向对象
    c++2
    c++1
    答疑:指针数组字符串
    文件操作
    用函数封装实现对一个数组增删改查
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5767077.html
Copyright © 2011-2022 走看看