首页 > 代码库 > [Usaco2006 Dec]Milk Patterns
[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 212323231
Sample Output
4
Source
后缀数组
答案应该是height数组中连续K-1个值的最小值的最大值。
这题还是要先离散化一下,不然可能会MLE
#include<cstdio>#include<cstring>#include<algorithm>#define maxn 30010using namespace std;char ch;int n,k,max_val,tot,head,tail,s[maxn],num[maxn],SA[maxn],rank[maxn],tmp[maxn],sum[maxn],height[maxn];struct DATA{ int val,tim;}list[maxn];inline bool isdigit(char ch){return ‘0‘<=ch&&ch<=‘9‘;}inline void read(int &x){ for (ch=getchar();!isdigit(ch);ch=getchar()); for (x=0;isdigit(ch);x=x*10+ch-‘0‘,ch=getchar());}inline bool cmp(int a,int b){return s[a]<s[b];}void prepare(){ sort(num+1,num+1+n,cmp); for (int i=1,pre=-1;i<=n;i++){ if (s[num[i]]!=pre) pre=s[num[i]],++max_val; s[num[i]]=max_val; }}void get_SA(){ for (int i=1;i<=n;i++) sum[tmp[i]=s[i]]++; for (int i=1;i<=max_val;i++) sum[i]+=sum[i-1]; for (int i=n;i>=1;i--) SA[sum[tmp[i]]--]=i; rank[SA[1]]=tot=1; for (int i=2;i<=n;i++){ if (tmp[SA[i]]!=tmp[SA[i-1]]) tot++; rank[SA[i]]=tot; } for (int len=1;len<=n;len<<=1){ memset(sum,0,sizeof(sum)); for (int i=1;i<=n;i++) sum[rank[i+len]]++; for (int i=1;i<=n;i++) sum[i]+=sum[i-1]; for (int i=n;i>=1;i--) tmp[sum[rank[i+len]]--]=i; memset(sum,0,sizeof(sum)); for (int i=1;i<=n;i++) sum[rank[tmp[i]]]++; for (int i=1;i<=n;i++) sum[i]+=sum[i-1]; for (int i=n;i>=1;i--) SA[sum[rank[tmp[i]]]--]=tmp[i]; tmp[SA[1]]=tot=1; for (int i=2;i<=n;i++){ if (rank[SA[i]]!=rank[SA[i-1]]||rank[SA[i]+len]!=rank[SA[i-1]+len]) tot++; tmp[SA[i]]=tot; } for (int i=1;i<=n;i++) rank[i]=tmp[i]; }}void get_height(){ for (int i=1,j=0;i<=n;i++){ if (rank[i]==1) continue; while (s[i+j]==s[SA[rank[i]-1]+j]) j++; height[rank[i]]=j; if (j>0) j--; }}int main(){ read(n),read(k); for (int i=1;i<=n;i++) read(s[i]),num[i]=i; prepare(),get_SA(),get_height(); k--,head=1,tail=0,max_val=0; for (int i=2;i<=n;i++){ while (head<=tail&&i-list[head].tim>=k) head++; while (head<=tail&&height[i]<list[tail].val) tail--; list[++tail]=(DATA){height[i],i}; if (i>k&&max_val<list[head].val) max_val=list[head].val; } printf("%d\n",max_val); return 0; }
[Usaco2006 Dec]Milk Patterns
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。