POJ 3261 Milk Patterns 可重复k次的最长重复子串
2015-08-10 21:20
295 查看
[b]Milk Patterns[/b]
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://poj.org/problem?id=3261
Description
Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he can't predict the quality of milk from one day to the next, there are some regular patterns in the daily milk quality.
To perform a rigorous study, he has invented a complex classification scheme by which each milk sample is recorded as an integer between 0 and 1,000,000 inclusive, and has recorded data from a single cow over N (1 ≤ N ≤ 20,000) days. He wishes to find the longest pattern of samples which repeats identically at least K (2 ≤ K ≤ N) times. This may include overlapping patterns -- 1 2 3 2 3 2 3 1 repeats 2 3 2 3 twice, for example.
Help Farmer John by finding the longest repeating subsequence in the sequence of samples. It is guaranteed that at least one subsequence is repeated at least K times.
Input
Line 1: Two space-separated integers: N and K
Lines 2..N+1: N integers, one per line, the quality of the milk on day i appears on the ith line.
Output
Line 1: One integer, the length of the longest pattern which occurs at least K times
Sample Input
8 2
1
2
3
2
3
2
3
1
Sample Output
4
HINT
题意
让你找到最长的可以重复k次的重复子串
题解:
后缀数组,跑出height数组之后,然后直接二分然后O(n),check就好了
跑check的时候,只要符合num++就好了,如果大于等于,那就是符合的,然后就好了……
代码:
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://poj.org/problem?id=3261
Description
Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he can't predict the quality of milk from one day to the next, there are some regular patterns in the daily milk quality.
To perform a rigorous study, he has invented a complex classification scheme by which each milk sample is recorded as an integer between 0 and 1,000,000 inclusive, and has recorded data from a single cow over N (1 ≤ N ≤ 20,000) days. He wishes to find the longest pattern of samples which repeats identically at least K (2 ≤ K ≤ N) times. This may include overlapping patterns -- 1 2 3 2 3 2 3 1 repeats 2 3 2 3 twice, for example.
Help Farmer John by finding the longest repeating subsequence in the sequence of samples. It is guaranteed that at least one subsequence is repeated at least K times.
Input
Line 1: Two space-separated integers: N and K
Lines 2..N+1: N integers, one per line, the quality of the milk on day i appears on the ith line.
Output
Line 1: One integer, the length of the longest pattern which occurs at least K times
Sample Input
8 2
1
2
3
2
3
2
3
1
Sample Output
4
HINT
题意
让你找到最长的可以重复k次的重复子串
题解:
后缀数组,跑出height数组之后,然后直接二分然后O(n),check就好了
跑check的时候,只要符合num++就好了,如果大于等于,那就是符合的,然后就好了……
代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define maxn 1005000 #define mod 10007 #define eps 1e-9 int Num; char CH[20]; //const int inf=0x7fffffff; //нчоч╢С const int inf=0x3f3f3f3f; inline ll read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } //************************************************************************************** int s[2*maxn]; int a[maxn]; int n,k; int sa[maxn], rank[maxn], height[maxn]; int wa[maxn], wb[maxn], wv[maxn], wd[maxn]; int cmp(int *r, int a, int b, int l){ return r[a] == r[b] && r[a+l] == r[b+l]; } void build_sa(int *r, int n, int m){ // 倍增算法 r为待匹配数组 n为总长度 m为字符范围 int i, j, p, *x = wa, *y = wb, *t; for(i = 0; i < m; i ++) wd[i] = 0; for(i = 0; i < n; i ++) wd[x[i]=r[i]] ++; for(i = 1; i < m; i ++) wd[i] += wd[i-1]; for(i = n-1; i >= 0; i --) sa[-- wd[x[i]]] = i; for(j = 1, p = 1; p < n; j *= 2, m = p){ for(p = 0, i = n-j; i < n; i ++) y[p ++] = i; for(i = 0; i < n; i ++) if(sa[i] >= j) y[p ++] = sa[i] - j; for(i = 0; i < n; i ++) wv[i] = x[y[i]]; for(i = 0; i < m; i ++) wd[i] = 0; for(i = 0; i < n; i ++) wd[wv[i]] ++; for(i = 1; i < m; i ++) wd[i] += wd[i-1]; for(i = n-1; i >= 0; i --) sa[-- wd[wv[i]]] = y[i]; for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; i ++){ x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p - 1: p ++; } } } void calHeight(int *r, int n){ // 求height数组。 int i, j, k = 0; for(i = 1; i <= n; i ++) rank[sa[i]] = i; for(i = 0; i < n; height[rank[i ++]] = k){ for(k ? k -- : 0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k ++); } } int check(int mid) { int num=0; for(int i=0;i<n;i++) { if(height[i]>=mid) num++; else num=1; if(num>=k) return 1; } return 0; } int main() { n=read(),k=read(); for(int i=0;i<n;i++) a[i]=read(),a[i]++; a[n++]=0; build_sa(a,n,1001000); calHeight(a,n); int l=0,r=n; while(l<=r) { int mid=(l+r)>>1; if(check(mid)) { l=mid+1; } else r=mid-1; } cout<<r<<endl; }
相关文章推荐
- 根据字符分割字符串
- Hibernate学习笔记(五) — 多对多关系映射
- 面试官的技术面试技巧与步骤
- 考试
- Borg Maze【POJ--3026】【并查集】
- 产品项目生命周期中的各种文档
- 115个Java面试题和答案——终极列表(上)
- [2015hdu多校联赛补题]hdu5302 Connect the Graph
- 一些项目需要的东西整合(1)——九款按钮
- 用过滤器解决全站中文数据提交乱码问题
- 【算法笔记】Aho-Corasick 算法(AC自动机) 小结
- MapReduce的处理流程(一)
- 重构与模式--泛化
- http get/post解决乱码问题
- poj 3349 Snowflake Snow Snowflakes
- 国外网站淘来的invocie java代码
- hdoj 1513 Palindrome 【LCS】【滚动数组】
- typedef函数指针与函数类型的定义及使用方式
- Spring MVC入门实例
- ios测试的时候出现错误