首页 技术 正文
技术 2022年11月14日
0 收藏 606 点赞 2,124 浏览 1773 个字

题目链接: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 ;
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,905
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,430
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,247
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,058
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,690
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,727