zoukankan      html  css  js  c++  java
  • [Usaco2006 Dec]Milk Patterns

    [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
    

    Source

    后缀数组

    答案应该是height数组中连续K-1个值的最小值的最大值。

    这题还是要先离散化一下,不然可能会MLE

    code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define maxn 30010
     5 using namespace std;
     6 char ch;
     7 int n,k,max_val,tot,head,tail,s[maxn],num[maxn],SA[maxn],rank[maxn],tmp[maxn],sum[maxn],height[maxn];
     8 struct DATA{
     9     int val,tim;
    10 }list[maxn];
    11 inline bool isdigit(char ch){return '0'<=ch&&ch<='9';}
    12 inline void read(int &x){
    13     for (ch=getchar();!isdigit(ch);ch=getchar());
    14     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
    15 }
    16 inline bool cmp(int a,int b){return s[a]<s[b];}
    17 void prepare(){
    18     sort(num+1,num+1+n,cmp);
    19     for (int i=1,pre=-1;i<=n;i++){
    20         if (s[num[i]]!=pre) pre=s[num[i]],++max_val;
    21         s[num[i]]=max_val;
    22     }
    23 }
    24 void get_SA(){
    25     for (int i=1;i<=n;i++) sum[tmp[i]=s[i]]++;
    26     for (int i=1;i<=max_val;i++) sum[i]+=sum[i-1];
    27     for (int i=n;i>=1;i--) SA[sum[tmp[i]]--]=i;
    28     rank[SA[1]]=tot=1;
    29     for (int i=2;i<=n;i++){
    30         if (tmp[SA[i]]!=tmp[SA[i-1]]) tot++;
    31         rank[SA[i]]=tot;    
    32     }
    33     for (int len=1;len<=n;len<<=1){
    34         memset(sum,0,sizeof(sum));
    35         for (int i=1;i<=n;i++) sum[rank[i+len]]++;
    36         for (int i=1;i<=n;i++) sum[i]+=sum[i-1];
    37         for (int i=n;i>=1;i--) tmp[sum[rank[i+len]]--]=i;
    38         memset(sum,0,sizeof(sum));
    39         for (int i=1;i<=n;i++) sum[rank[tmp[i]]]++;
    40         for (int i=1;i<=n;i++) sum[i]+=sum[i-1];
    41         for (int i=n;i>=1;i--) SA[sum[rank[tmp[i]]]--]=tmp[i];
    42         tmp[SA[1]]=tot=1;
    43         for (int i=2;i<=n;i++){
    44             if (rank[SA[i]]!=rank[SA[i-1]]||rank[SA[i]+len]!=rank[SA[i-1]+len]) tot++;
    45             tmp[SA[i]]=tot;    
    46         }
    47         for (int i=1;i<=n;i++) rank[i]=tmp[i];        
    48     }
    49 }
    50 void get_height(){
    51     for (int i=1,j=0;i<=n;i++){
    52         if (rank[i]==1) continue;
    53         while (s[i+j]==s[SA[rank[i]-1]+j]) j++;    
    54         height[rank[i]]=j;
    55         if (j>0) j--;
    56     }
    57 }
    58 int main(){
    59     read(n),read(k);
    60     for (int i=1;i<=n;i++) read(s[i]),num[i]=i;
    61     prepare(),get_SA(),get_height();
    62     k--,head=1,tail=0,max_val=0;
    63     for (int i=2;i<=n;i++){
    64         while (head<=tail&&i-list[head].tim>=k) head++;
    65         while (head<=tail&&height[i]<list[tail].val) tail--;
    66         list[++tail]=(DATA){height[i],i};
    67         if (i>k&&max_val<list[head].val) max_val=list[head].val;
    68     }
    69     printf("%d
    ",max_val);
    70     return 0;    
    71 }
  • 相关阅读:
    构建之法阅读笔记05
    构建之法阅读笔记04
    大二上学期软件工程概论学习进度表(第十二周)
    构建之法阅读笔记03
    四则运算二
    GCD
    Category的使用
    适配6 、6P 来源互联网
    UIView阴影和圆角的关系
    NSSet类型 以及与NSArray区别
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/4124834.html
Copyright © 2011-2022 走看看