zoukankan      html  css  js  c++  java
  • bzoj1717

    [Usaco2006 Dec]Milk Patterns 产奶的模式

    Description

    农夫John发现他的奶牛产奶的质量一直在变动。经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠。我们称之为一个“模式”。 John的牛奶按质量可以被赋予一个0到1000000之间的数。并且John记录了N(1<=N<=20000)天的牛奶质量值。他想知道最长的出现了至少K(2<=K<=N)次的模式的长度。比如1 2 3 2 3 2 3 1 中 2 3 2 3出现了两次。当K=2时,这个长度为4。

    Input

    * Line 1: 两个整数 N,K。

    * Lines 2..N+1: 每行一个整数表示当天的质量值。

    Output

    * Line 1: 一个整数:N天中最长的出现了至少K次的模式的长度

    Sample Input

    8 2
    1
    2
    3
    2
    3
    2
    3
    1

    Sample Output

    4
     
    *******************************************************************************************************************************************

    题意:给定长为N的数组,问重复次数不小于K的最长区间长度。

    首先,我们应该了解到所有后缀的前缀就是所有的子串。所以,相同子串那么他们的rank[]一定相临。想长度大小就是height[].

    所以,height[]中连续连续k个数中最小值最大。所以二分值的大小,依次判断就可以了。

    应该用单调队列也可以了,没有试过。

    ***********************************************************************************************

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=20010;
     4 int s[maxn],sa[maxn],rank[maxn],saf[maxn],cs[maxn],height[maxn];
     5 int n,m,cc,kk;
     6 void init()
     7 {
     8     scanf("%d%d",&n,&cc);
     9     for(int i=1;i<=n;++i)scanf("%d",&s[i]),m=max(m,s[i]);
    10     s[0]=s[n+1]=-1;
    11 }
    12 void rsort()
    13 {
    14     for(int i=0;i<=m;++i)cs[i]=0;
    15     for(int i=1;i<=n;++i)cs[rank[saf[i]]]++;
    16     for(int i=1;i<=m;++i)cs[i]+=cs[i-1];
    17     for(int i=n;i>=1;--i)sa[cs[rank[saf[i]]]--]=saf[i];
    18 }
    19 int cmp(int *f,int x,int y,int w)
    20 {
    21     return f[x]==f[y] && f[x+w]==f[y+w];
    22 }
    23 void suffix()
    24 {
    25     for(int i=1;i<=n;++i)rank[i]=s[i],saf[i]=i;
    26     rsort();
    27     for(int p=1,w=1,i;p<n;w<<=1,m=p)
    28     {
    29         for(i=n-w+1,p=0;i<=n;++i)saf[++p]=i;
    30         for(i=1;i<=n;++i)if(sa[i]>w)saf[++p]=sa[i]-w;
    31         rsort();swap(rank,saf);rank[sa[1]]=p=1;
    32         for(int i=2;i<=n;++i)rank[sa[i]]=cmp(saf,sa[i],sa[i-1],w)?p:++p;
    33     }
    34     int j,k=0;
    35     for(int i=1;i<=n;height[rank[i++]]=k)
    36         for(k=k?k-1:k,j=sa[rank[i]-1];s[i+k]==s[j+k];++k);
    37 }
    38 bool pd(int x)
    39 {
    40     int num=0;
    41     for(int i=1;i<=n;++i)
    42     {
    43         if(height[i]>=x)
    44         {
    45             num++;
    46             if(num>=cc-1)return 1;
    47         }
    48         else num=0;
    49     }
    50     return 0;
    51 }
    52 int main()
    53 {
    54     init();
    55     suffix();
    56     int l=1,r=n,ans;
    57     while(l<=r)
    58     {
    59         int mid=(l+r)>>1;
    60         if(pd(mid))ans=mid,l=mid+1;
    61         else r=mid-1;
    62     }
    63     cout<<ans;
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    20172302 201720182 《程序设计与数据结构》实验二报告
    20172302 201720182 《程序设计与数据结构》实验一报告
    20172302 《程序设计与数据结构》第五周学习总结
    POJ 1061 青蛙的约会
    hdu 2485 Highways
    UVA 10608
    hdu 1213 how many tables
    java类static成员加载顺寻
    C# virtual,override或者new
    vs无法在WEB服务器上启动调试
  • 原文地址:https://www.cnblogs.com/gryzy/p/8284564.html
Copyright © 2011-2022 走看看