题目链接:https://cn.vjudge.net/contest/283743#problem/D

题目大意:给你n个数,然后问你出现m次的最长子串的长度。

具体思路:和上一篇博客的内容差不多,这个是可重复的,就不需要考虑sa的问题了,每一次还是二分答案,判断出现的最长前缀就可以了。注意二分的时候,每一次的寻找,初始值为1,因为这个字符串就已经出现过一次了。

AC代码:

 #include<iostream>
#include<stack>
#include<cstring>
#include<iomanip>
#include<stdio.h>
#include<algorithm>
#include<cmath>
using namespace std;
# define ll long long
# define inf 0x3f3f3f3f
const int maxn = 5e6+;
int cntA[maxn], cntB[maxn], sa[maxn], tsa[maxn], A[maxn], B[maxn], height[maxn];
int Rank[maxn];
int ch[maxn];
int sto[maxn];
ll n,m;
//sa[i]代表第i小的后缀位置,Rank[i]代表第i位置的后缀,排名第几小
// height[i]代表排名第i个字符串和第i-1个字符串的相同前缀有多少个
void cal(int maxx)
{
for(int i = ; i <=maxx; i++)
cntA[i] = ;
// cout<<1<<endl;
// cout<<n<<endl;
for(int i = ; i <= n; i++)
{
//cout<<ch[i-1]<<endl;
cntA[ch[i-]]++;
}
// cout<<1<<endl;
for(int i = ; i <= maxx; i++)
cntA[i] += cntA[i-];
for(int i = n; i; i--)
sa[cntA[ch[i-]]--] = i;
Rank[sa[]] = ;
for(int i = ; i <= n; i++)
{
Rank[sa[i]] = Rank[sa[i-]];
if(ch[sa[i]-] != ch[sa[i-]-])
Rank[sa[i]]++;
}
for(int l = ; Rank[sa[n]] < n; l <<= )
{
memset(cntA, , sizeof(cntA));
memset(cntB, , sizeof(cntB));
for(int i = ; i <= n; i++)
{
cntA[A[i] = Rank[i]]++;
cntB[B[i] = (i+l <= n)?Rank[i+l]:]++;
}
for(int i = ; i <= n; i++)
cntB[i] += cntB[i-];
for(int i = n; i; i--)
tsa[cntB[B[i]]--] = i;
for(int i = ; i <= n; i++)
cntA[i] += cntA[i-];
for(int i = n; i; i--)
sa[cntA[A[tsa[i]]]--] = tsa[i];
Rank[sa[]]=;
for(int i = ; i <= n; i++)
{
Rank[sa[i]] = Rank[sa[i-]];
if(A[sa[i]] != A[sa[i-]] || B[sa[i]] != B[sa[i-]])
Rank[sa[i]]++;
}
}
for(int i = , j = ; i <= n; i++)
{
if(j)
j--;
while(ch[i+j-] == ch[sa[Rank[i]-] + j - ])
j++;
height[Rank[i]] = j;
}
}
bool judge(int t)
{
int ans=;
for(int i=; i<=n; i++)
{
if(height[i]>=t)
{
ans++;
}
else
{
ans=;
}
if(ans>=m)
return true;
}
return false;
}
int main()
{
int maxx=;
scanf("%lld %lld",&n,&m);
for(int i=; i<=n; i++)
{
scanf("%d",&ch[i]);
maxx=max(maxx,ch[i]);
}
cal(maxx);
int l=,r=1e8,ans=;
while(l<=r)
{
int mid=(l+r)>>;
if(judge(mid))
{
ans=mid;
l=mid+;
}
else
{
r=mid-;
}
}
printf("%d\n",ans);
return ;
}

D - Milk Patterns (出现k次可重复的最长子串的长度)的更多相关文章

  1. LeetCode: 3_Longest Substring Without Repeating Characters | 求没有重复字符的最长子串的长度 | Medium

    题目: Given a . For . 解题思路: 这个题让找一个字符串中具有不重复单词的最长子串的长度,如:ababc,子串为abc,长度为3.有这么几个方法: 方法一: 依赖字符串本身的一些特有函 ...

  2. POJ-3294-Life Forms(后缀数组-不小于 k 个字符串中的最长子串)

    题意: 给定 n 个字符串,求出现在不小于 k 个字符串中的最长子串. 分析: 将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组. 然后二分答案,将后缀分成若干组,判断 ...

  3. 【LeetCode】无重复字符串最长子串

    题目描述 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "a ...

  4. 【leetcode-03】给定一个字符串,请你找出其中不含有重复字符的最长子串的长度

    开个新坑,leetcode上面做题目.下面是题目描述: <!-- 给定一个字符串,请你找出其中不含有重复字符的最长子串的长度. 示例 1: 输入: "abcabcbb" 输出 ...

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

    Milk Patterns   Description Farmer John has noticed that the quality of milk given by his cows varie ...

  6. POJ 3261 出现至少K次的可重叠最长子串

    题意就是给一列数字,求最长的一个子串,并且满足子串在原数串中出现至少K次,子串可以重叠. 解法是将问题转为判定性问题,二分子串的长度,判定是否满足重复至少K次.判定方法是经典的根据子串长度将Heigh ...

  7. [LeetCode] 340. Longest Substring with At Most K Distinct Characters 最多有K个不同字符的最长子串

    Given a string, find the length of the longest substring T that contains at most k distinct characte ...

  8. UVa 11107 生命的形式(不小于k个字符串中的最长子串)

    https://vjudge.net/problem/UVA-11107 题意:给定n个字符串,求出现在不小于n的一半个字符串的最长子串,如果有多个,则按字典序输出. 思路: 首先就是将这n个字符串连 ...

  9. poj 3294 后缀数组 多字符串中不小于 k 个字符串中的最长子串

    Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 16223   Accepted: 4763 Descr ...

随机推荐

  1. jenkins--svn基本使用

    新建项目 源码管理  #选择svn配置 svn基本信息配置 其中包括: Repository URL:  svn://10.101.0.XXX:9507/XXXX Credentials:  配置你的 ...

  2. BZOJ3835[Poi2014]Supercomputer——斜率优化

    题目描述 Byteasar has designed a supercomputer of novel architecture. It may comprise of many (identical ...

  3. HS BDC HDU - 3472(混合欧拉路径)

    题意: 就是混合欧拉路径板题 解析: 欧拉路径加一条t_ ---> s_  的边就变成了欧拉回路,所以利用这一点,如果存在两个奇点,那么这两个奇点出度大的是s_,入度大的是t_,加一条t_ -- ...

  4. Network POJ - 3694 (连通图标求桥)

    有上述两个数组定义可知:对于某点root,其有一儿子v,则有: 1.     如果dfn[root]<=low[v]此点是割点(对于dfs树的根,即最初节点需要两个儿子才是割点) 2.      ...

  5. MT【28】内心外衣下的等腰三角形个数

    解答:30 评:这道题倒不是传统的与内心相关的向量题,传统的与内心或者内切圆有关的两个结论是aIA+bIB+cIC=0以及所谓的"人品公式"S=rp.这里主要是得到此三角形为以AC ...

  6. Fail2ban 配置

    本例为wordpress管理员登陆限制安装rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.n ...

  7. Python基础之控制流

    介绍一些Python的基本的东西,你会发现,Python真的很简单.我也尽可能说得简单一些,因为我理解的也很简单. 在到目前为止我们所见到的程序中,总是有一系列的语句,Python忠实地按照它们的顺序 ...

  8. 自学Aruba5.3.3-Aruba安全认证-有PEFNG 许可证环境的认证配置Captive-Portal

    点击返回:自学Aruba之路 自学Aruba5.3.3-Aruba安全认证-有PEFNG 许可证环境的认证配置Captive-Portal 1. Captive-Portal认证配置前言 1.1 新建 ...

  9. Spark安装与介绍

    1. Scala的安装 注意点:版本匹配的问题, Spark 1.6.2 -- Scala2.10 Spark 2.0.0 -- Scala2.11 https://www.scala-lang.or ...

  10. Java -- JDBC_利用反射及 JDBC 元数据编写通用的查询方法

    先利用 SQL 进行查询,得到结果集: 利用反射创建实体类的对象:创建对象: 获取结果集的列的别名: 再获取结果集的每一列的值, 结合 3 得到一个 Map,键:列的别名,值:列的值: 再利用反射为 ...