后缀数组+二分答案+离散化。(上次写的时候看数据小没离散化然后一直WA。。。写了lsj师兄的写法。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define REP(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define clr(x,c) memset(x,c,sizeof(x))
int read(){
int x=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return x;
}
const int nmax=20005;
const int inf=0x7f7f7f7f; struct node{
int id[nmax],N;
node(){
N=0;
}
inline void add(int x){
id[N++]=x;
}
inline void work(){
sort(id,id+N);
N=unique(id,id+N)-id;
}
inline int hash(int x){
return lower_bound(id,id+N,x)-id;
}
}h; int sa[nmax],t[nmax],t2[nmax],c[nmax],rank[nmax],height[nmax],S[nmax],N,K;
void build_sa(){
int m=h.N,*x=t,*y=t2;
for(int i=0;i<m;i++) c[i]=0;
for(int i=0;i<N;i++) c[x[i]=S[i]]++;
for(int i=1;i<m;i++) c[i]+=c[i-1];
for(int i=N-1;i>=0;i--) sa[--c[x[i]]]=i;
for(int k=1;k<=N;k<<=1){
int p=0;
for(int i=N-k;i<N;i++) y[p++]=i;
for(int i=0;i<N;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(int i=0;i<m;i++) c[i]=0;
for(int i=0;i<N;i++) c[x[i]]++;
for(int i=1;i<m;i++) c[i]+=c[i-1];
for(int i=N-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i];
swap(x,y);p=1;x[sa[0]]=0;
for(int i=1;i<N;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
if(p>=N) break;
m=p;
}
} void build_height(){
int k=0;
for(int i=0;i<N;i++) rank[sa[i]]=i;
for(int i=0;i<N;i++){
if(k) k--;
int j=sa[rank[i]-1];
while(S[i+k]==S[j+k]) k++;
height[rank[i]]=k;
}
} bool check(int x){
int cnt=1;
for(int i=1;i<N;i++){
if(height[i]>=x){
cnt++;
if(cnt>=K) return true;
}else cnt=1;
}
return false;
} int main(){
N=read(),K=read();
REP(i,0,N-1) S[i]=read(),h.add(S[i]);
h.add(S[N++]=-inf);h.work();
REP(i,0,N-1) S[i]=h.hash(S[i]); build_sa();build_height();
int l=0,r=N,ans=0,mid;
while(l<=r){
mid=(l+r)>>1;
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",ans);
return 0;
}

  

1717: [Usaco2006 Dec]Milk Patterns 产奶的模式

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 948  Solved: 516
[Submit][Status][Discuss]

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

HINT

 

Source

[Submit][Status][Discuss]

bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式的更多相关文章

  1. [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式_后缀数组_二分答案

    Milk Patterns 产奶的模式 bzoj-1717 Usaco-2006 Dec 题目大意:给定一个字符串,求最长的至少出现了$k$次的子串长度. 注释:$1\le n\le 2\cdot 1 ...

  2. bzoj1717: [Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+二分)

    /* 求可重叠的至少重复K次的最长字串 以1为下标起点,因为a[i]最大到1000000,所以要先离散一下 二分长度len 然后O(n)检验 后看h[i]是否有连续的一段h[i]大于len的,并且h[ ...

  3. [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式 (hash构造后缀数组,二分答案)

    以后似乎终于不用去学后缀数组的倍增搞法||DC3等blablaSXBK的方法了= = 定义(来自关于后缀数组的那篇国家集训队论文..) 后缀数组:后缀数组SA是一个一维数组,它保存1..n的某个排列S ...

  4. [bzoj1717][Usaco2006 Dec]Milk Patterns 产奶的模式——后缀数组

    Brief Description 给定一个字符串,求至少出现k次的最长重复子串. Algorithm Design 先二分答案,然后将后缀分成若干组.判断有没有一个组的后缀个数不小于k.如果有,那么 ...

  5. BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 [后缀数组]

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1017  Solved: ...

  6. BZOJ 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式( 二分答案 + 后缀数组 )

    二分答案m, 后缀数组求出height数组后分组来判断. ------------------------------------------------------------ #include&l ...

  7. BZOJ#1717:[Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+单调队列)

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的 ...

  8. BZOJ_1717_[Usaco2006 Dec]Milk Patterns 产奶的模式_后缀数组

    BZOJ_1717_[Usaco2006 Dec]Milk Patterns 产奶的模式_后缀数组 Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他 ...

  9. 1717: [Usaco2006 Dec]Milk Patterns 产奶的模式

    1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1469  Solved: ...

随机推荐

  1. bnuoj 4207 台风(模拟题)

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=4207 [题意]:中文题,略 [题解]:模拟 [code]: #include <iostrea ...

  2. python 获取文件大小,创建时间和访问时间

    # -*- coding: UTF8 -*- import timeimport datetime import os 1. '''把时间戳转化为时间: 1479264792 to 2016-11-1 ...

  3. vi 常用技巧

    vi/vim : Visual Interface/VI iMproved VI命令可以说是Unix/Linux世界里最常用的编辑文件的命令了,但是因为它的命令集众多,很多人都不习惯使用它,其实您只需 ...

  4. c++ switch case

    http://www.cnblogs.com/RealOnlyme/articles/2579628.html

  5. Linq常用

    1.左关联查询var lst = from m in db.信息          join d in db.明细信息          on m.单号 equals d.单号 into mi     ...

  6. 【POJ】【2348】Euclid‘s Game

    博弈论 题解:http://blog.sina.com.cn/s/blog_7cb4384d0100qs7f.html 感觉本题关键是要想到[当a-b>b时先手必胜],后面的就只跟奇偶性有关了 ...

  7. C#枚举注释实例

    public enum 枚举名称    {        /// <summary>        /// 注释描述1        /// </summary>        ...

  8. OD鲜为人知的小技巧--搜索通配符(关键字)

    我看过一些OD教程,关于通配符这一点很少有人讲解(大概是我看的教程少吧)  近日通过看<黑客反汇编揭秘(第二版)>第165页了解到,原来OD还有这样方便的功能,那就是搜索通配符: Olly ...

  9. java 几种常见的定时器

    今天闲着没事就总结了一下在java中常用的几种定时器. 主要有3种java.util.Timer, ScheduledExecutorService和quartz 一.Timer 举个简单例子.每隔5 ...

  10. jquery css 简单笔记

    内容 要点:清空表单中所有数据,除去 button,submit,reset,hidden 的数据 $(':input','#myform') .not(':button, :submit, :res ...