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

Luogu

一句话题意

给出一个串,求至少出现了\(K\)次的子串的最长长度。

sol

对这个串求后缀数组。
二分最长长度。
如果有\(K\)个不同后缀他们两两的\(lcp\)都\(>=mid\)
那么他们在\(SA\)中一定排在连续的一段区间,且两两之间的\(Height[i]>=mid\)
所以判断\(Height\)数组中是否存在长度大于等于\(K-1\)且数值全部大于等于\(mid\)的连续段。

code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define ll long long
int gi()
{
    int x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=0,ch=getchar();
    while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
const int N = 1e6+10;
int n,k,a[N],t[N],x[N],y[N],SA[N],Rank[N],Height[N];
bool cmp(int i,int j,int k){return y[i]==y[j]&&y[i+k]==y[j+k];}
void getSA()
{
    int m=1e6+5;
    for (int i=1;i<=n;++i) ++t[x[i]=a[i]];
    for (int i=1;i<=m;++i) t[i]+=t[i-1];
    for (int i=n;i>=1;--i) SA[t[x[i]]--]=i;
    for (int k=1;k<=n;k<<=1)
    {
        int p=0;
        for (int i=0;i<=m;++i) y[i]=0;
        for (int i=n-k+1;i<=n;++i) y[++p]=i;
        for (int i=1;i<=n;++i) if (SA[i]>k) y[++p]=SA[i]-k;
        for (int i=0;i<=m;++i) t[i]=0;
        for (int i=1;i<=n;++i) ++t[x[y[i]]];
        for (int i=1;i<=m;++i) t[i]+=t[i-1];
        for (int i=n;i>=1;--i) SA[t[x[y[i]]]--]=y[i];
        swap(x,y);
        x[SA[1]]=p=1;
        for (int i=2;i<=n;++i) x[SA[i]]=cmp(SA[i],SA[i-1],k)?p:++p;
        if (p>=n) break;
        m=p;
    }
    for (int i=1;i<=n;++i) Rank[SA[i]]=i;
    for (int i=1,j=0;i<=n;++i)
    {
        if (j) --j;
        while (a[i+j]==a[SA[Rank[i]-1]+j]) ++j;
        Height[Rank[i]]=j;
    }
}
bool check(int mid)
{
    int cnt=0;
    for (int i=1;i<=n;++i)
    {
        if (Height[i]>=mid) ++cnt;else cnt=0;
        if (cnt==k-1) return true;
    }
    return false;
}
int main()
{
    n=gi();k=gi();
    for (int i=1;i<=n;++i) a[i]=gi()+1;
    getSA();
    int l=0,r=n;
    while (l<r)
    {
        int mid=l+r+1>>1;
        if (check(mid)) l=mid;
        else r=mid-1;
    }
    printf("%d\n",l);
    return 0;
}

原文地址:https://www.cnblogs.com/zhoushuyu/p/8467767.html

时间: 2024-08-30 15:32:12

[Luogu2852][USACO06DEC]牛奶模式Milk Patterns的相关文章

洛谷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 th

Luogu2852 [USACO06DEC]牛奶模式

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

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[

[BZOJ1717][Usaco2006 Dec]Milk Patterns 产奶的模式

1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1297  Solved: 705 [Submit][Status][Discuss] Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个"模式". John的牛奶按质量可以被赋予一个0到100

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

1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1017  Solved: 561[Submit][Status][Discuss] Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个“模式”. John的牛奶按质量可以被赋予一个0到1000000之间的

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

二分答案m, 后缀数组求出height数组后分组来判断. ------------------------------------------------------------ #include<bits/stdc++.h> using namespace std; const int maxn = 20009; struct HASH { int id[maxn], N; HASH() { N = 0; } inline void work() { sort(id, id + N); N

【BZOJ-1717】Milk Patterns产奶的模式 后缀数组

1717: [Usaco2006 Dec]Milk Patterns 产奶的模式 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 881  Solved: 480[Submit][Status][Discuss] Description 农夫John发现他的奶牛产奶的质量一直在变动.经过细致的调查,他发现:虽然他不能预见明天产奶的质量,但连续的若干天的质量有很多重叠.我们称之为一个“模式”. John的牛奶按质量可以被赋予一个0到1000000之间的数

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

Milk Patterns 产奶的模式 bzoj-1717 Usaco-2006 Dec 题目大意:给定一个字符串,求最长的至少出现了$k$次的子串长度. 注释:$1\le n\le 2\cdot 10^4$,$2\le k\le n$. 想法:不难想到二分答案,现在我们考虑如何验证. 这里就是后缀数组的一个妙用了. 我们对原串建立后缀数组,观察$ht$数组. 考虑当前二分出来的$mid$.如果有至少连续$k$的$ht$值都不小于$mid$,那么$k$就是合法的. 故此我们直接扫$ht$数组看看

POJ 3261 Milk Patterns 后缀数组求 一个串种 最长可重复子串重复至少k次

Milk Patterns 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 r