洛谷P2852 [USACO06DEC]牛奶模式Milk Patterns

题目描述

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.

农夫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。

输入输出格式

输入格式:

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.

输出格式:

Line 1: One integer, the length of the longest pattern which occurs at least K times

输入输出样例

输入样例#1: 复制

8 2
1
2
3
2
3
2
3
1

输出样例#1: 复制

4

自己YY了一波没想到居然1A哈哈

这题很明显,就是求Height数组,

求完之后二分一个长度,检验一下这个长度出现的次数是否满足要求

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN=200001,INF=2*1e9+10;
inline char nc()
{
    static char buf[MAXN],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
    char c=nc();int x=0,f=1;
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=nc();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=nc();}
    return x*f;
}
int N,M,K;
int a[MAXN],sa[MAXN],tax[MAXN],tp[MAXN],rak[MAXN],Height[MAXN];
inline void Qsort()
{
    for(int i=1;i<=M;i++) tax[i]=0;
    for(int i=1;i<=N;i++) tax[rak[i]]++;
    for(int i=1;i<=M;i++) tax[i]+=tax[i-1];
    for(int i=N;i>=1;i--) sa[ tax[rak[tp[i]]]-- ] = tp[i];
}
int check(int val)
{
    int cur=0;
    for(int i=1;i<=N;i++)
    {
        if(Height[i]<val) cur=0;
        else cur++;
        if(cur>=K-1) return 1;
    }
    return 0;
}
inline void Ssort()
{
    M=10001;
    for(int i=1;i<=N;i++) rak[i]=a[i],tp[i]=i;Qsort();
    for(int w=1,p=1; p<N ; M=p,w<<=1)
    {
        p=0;
        for(int i=N-w+1;i<=N;i++) tp[++p]=i;
        for(int i=1;i<=N;i++) if(sa[i]>w) tp[++p]=sa[i]-w;
        Qsort();swap(rak,tp);rak[sa[1]]=p=1;
        for(int i=2;i<=N;i++) rak[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+w]==tp[sa[i-1]+w])?p:++p;
    }
    int j,k=0;
//    for(int i=1;i<=N;i++) printf("%d ",sa[i]);printf("\n");
    for(int i=1;i<=N;Height[rak[i++]]=k)
        for( k=(k?k-1:k),j=sa[rak[i]-1];a[i+k]==a[j+k];++k);
//    for(int i=1;i<=N;i++) printf("%d ",Height[i]);
    int l=1,r=N,ans=0;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(check(mid)) ans=mid,l=mid+1;
        else r=mid-1;
    }
    printf("%d",ans);
}
int main()
{
    #ifdef WIN32
    freopen("a.in","r",stdin);
    #else
    #endif
    N=read();K=read();
    for(int i=1;i<=N;i++) a[i]=read();
    Ssort();
    return  0;
}

原文地址:https://www.cnblogs.com/zwfymqz/p/8413314.html

时间: 2024-08-01 13:59:36

洛谷P2852 [USACO06DEC]牛奶模式Milk Patterns的相关文章

[Luogu2852][USACO06DEC]牛奶模式Milk Patterns

Luogu 一句话题意 给出一个串,求至少出现了\(K\)次的子串的最长长度. sol 对这个串求后缀数组. 二分最长长度. 如果有\(K\)个不同后缀他们两两的\(lcp\)都\(>=mid\) 那么他们在\(SA\)中一定排在连续的一段区间,且两两之间的\(Height[i]>=mid\) 所以判断\(Height\)数组中是否存在长度大于等于\(K-1\)且数值全部大于等于\(mid\)的连续段. code #include<cstdio> #include<algor

洛谷P3093 [USACO13DEC]牛奶调度Milk Scheduling

题目描述 Farmer John has N cows that need to be milked (1 <= N <= 10,000), each of which takes only one unit of time to milk. Being impatient animals, some cows will refuse to be milked if Farmer John waits too long to milk them. More specifically, cow

洛谷 P3063 [USACO12DEC]牛奶的路由Milk Routing

P3063 [USACO12DEC]牛奶的路由Milk Routing 题目背景 征求翻译.如果你能提供翻译或者题意简述,请直接发讨论,感谢你的贡献. 题目描述 Farmer John's farm has an outdated network of M pipes (1 <= M <= 500) for pumping milk from the barn to his milk storage tank. He wants to remove and update most of the

洛谷 P2853 [USACO06DEC]牛的野餐Cow Picnic

P2853 [USACO06DEC]牛的野餐Cow Picnic dfs 1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,k,p[10000],can[10000]; 4 int w[1000+15][1000+15]; 5 bool vis[10000]; 6 7 void dfs(int pre) 8 { 9 for(int j=1;j<=n;j++) 10 { 11 if(w[pre][j]&&!

洛谷——P2853 [USACO06DEC]牛的野餐Cow Picnic

P2853 [USACO06DEC]牛的野餐Cow Picnic 题目描述 The cows are having a picnic! Each of Farmer John's K (1 ≤ K ≤ 100) cows is grazing in one of N (1 ≤ N ≤ 1,000) pastures, conveniently numbered 1...N. The pastures are connected by M (1 ≤ M ≤ 10,000) one-way path

Luogu2852 [USACO06DEC]牛奶模式

题目蓝链 Description 给定一个字符串,你需要找到一个最长在这个串中至少出现了\(k\)次的子串 Solution 我们首先对这个串进行后缀排序,那么对于排序后的任意一个区间\([l, r]\),那么原串中一定有\(r - l + 1\)个长度为\(MIN_{i \in (l, r]} \{height_i\}\)的相同字串 于是我们就直接把\(height\)数列扫一边,同时维护一个单调队列,来维护任意相邻的\(k - 1\)个\(height\)的最小值,答案便是这些最小值中的最大

洛谷P2853 [USACO06DEC]牛的野餐Cow Picnic

题目描述 The cows are having a picnic! Each of Farmer John's K (1 ≤ K ≤ 100) cows is grazing in one of N (1 ≤ N ≤ 1,000) pastures, conveniently numbered 1...N. The pastures are connected by M (1 ≤ M ≤ 10,000) one-way paths (no path connects a pasture to

洛谷 P2850 [USACO06DEC]虫洞Wormholes 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=2850 [题目描述] John在他的农场中闲逛时发现了许多虫洞.虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前).John的每个农场有M条小路(无向边)连接着N (从1..N标号)块地,并有W个虫洞(有向边).其中1<=N<=500,1<=M<=2500,1<=W<=200.

USACO06DEC 牛奶模式

题意:求最长的可重叠的 K重复子串 的长度 考虑二分长度s,转化为验证性问题. 对SA进行分组.保证组内Height最小为s.这样在组内RMQ就可以任意了,因为RMQ一定是大于S的. 只要组内元素个数大于等于K就是可行解. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 struct SA{ 5 int str[1000005]; 6 int x[1000005],y[1000005],u[1000005],v[1000005],r[