【后缀数组】【二分答案】poj3261
注意:对整型数组求sa时,s[n]请置成-1。
请离散化。
可重叠的 k 次最长重复子串(pku3261)
给定一个字符串,求至少出现 k 次的最长重复子串,这 k 个子串可以重叠。
算法分析:
先二分答案,然后将后缀分成若干组。 不
同的是,这里要判断的是有没有一个组的后缀个数不小于 k。如果有,那么存在
k 个相同的子串满足条件,否则不存在。这个做法的时间复杂度为 O(nlogn)。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 20001
struct Point{int p,v;}T[N];
bool operator < (Point a,Point b){return a.v<b.v;}
int s[N],tong[N],t[N],t2[N],rank[N],lcp[N],sa[N];
int n,K,zy=1,ma[N];
bool cmp(int *y,int i,int k)
{
return ((y[sa[i-1]]==y[sa[i]])&&((sa[i-1]+k>=n?-1:y[sa[i-1]+k])==(sa[i]+k>=n?-1:y[sa[i]+k])));
}
void build_sa(int range)
{
int *x=t,*y=t2;
memset(tong,0,sizeof(int)*range);
for(int i=0;i<n;++i) tong[x[i]=s[i]]++;
for(int i=1;i<range;++i) tong[i]+=tong[i-1];
for(int i=n-1;i>=0;--i) sa[--tong[x[i]]]=i;
for(int k=1;k<=n;k<<=1)
{
int p=0;
for(int i=n-k;i<n;++i) y[p++]=i;
for(int i=0;i<n;++i) if(sa[i]>=k) y[p++]=sa[i]-k;
memset(tong,0,sizeof(int)*range);
for(int i=0;i<n;++i) tong[x[y[i]]]++;
for(int i=1;i<range;++i) tong[i]+=tong[i-1];
for(int i=n-1;i>=0;--i) sa[--tong[x[y[i]]]]=y[i];
swap(x,y); p=1; x[sa[0]]=0;
for(int i=1;i<n;++i) x[sa[i]]=cmp(y,i,k)?p-1:p++;
if(p>=n) break;
range=p;
}
}
void get_lcp()
{
int k=0;
for(int i=0;i<n;++i) rank[sa[i]]=i;
for(int i=0;i<n;++i) if(rank[i])
{
if(k) --k;
int j=sa[rank[i]-1];
while(s[i+k]==s[j+k]) ++k;
lcp[rank[i]]=k;
}
}
bool check(int x)
{
int cnt=1;
for(int i=1;i<=n;++i)
{
if(lcp[i]<x||i==n)
{
if(cnt>=K) return 1;
cnt=1;
}
else if(lcp[i]>=x) ++cnt;
}
return 0;
}
int main()
{
scanf("%d%d",&n,&K);
for(int i=0;i<n;++i)
{
scanf("%d",&T[i].v);
T[i].p=i;
}
sort(T,T+n);
for(int i=1;i<n;++i)
{
if(T[i].v!=T[i-1].v) ++zy;
s[T[i].p]=zy-1;
}
s[n]=-1;
build_sa(zy);
get_lcp();
int l=0,r=n;
while(r>l)
{
int mid=(l+r+1>>1);
if(check(mid)) l=mid;
else r=mid-1;
}
printf("%d\n",l);
return 0;
}
【后缀数组】【二分答案】poj3261的更多相关文章
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单 ...
- Poj 1743 Musical Theme(后缀数组+二分答案)
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...
- Poj 3261 Milk Patterns(后缀数组+二分答案)
Milk Patterns Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk g ...
- POJ3294--Life Forms 后缀数组+二分答案 大于k个字符串的最长公共子串
Life Forms Time Limit: 500 ...
- SPOJ 220 Relevant Phrases of Annihilation(后缀数组+二分答案)
[题目链接] http://www.spoj.pl/problems/PHRASES/ [题目大意] 求在每个字符串中出现至少两次的最长的子串 [题解] 注意到这么几个关键点:最长,至少两次,每个字符 ...
- POJ 3261 Milk Patterns(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=3261 [题目大意] 求最长可允许重叠的出现次数不小于k的子串. [题解] 对原串做一遍后缀数组,二分子串长度x,将前缀相同长度超过 ...
- POJ 3294 Life Forms(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=3294 [题目大意] 求出在至少在一半字符串中出现的最长子串. 如果有多个符合的答案,请按照字典序输出. [题解] 将所有的字符串通 ...
- POJ 1743 Musical Theme(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=1743 [题目大意] 给出一首曲子的曲谱,上面的音符用不大于88的数字表示, 现在请你确定它主旋律的长度,主旋律指的是出现超过一次, ...
- POJ 1226 Substrings(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=1226 [题目大意] 求在每个给出字符串中出现的最长子串的长度,字符串在出现的时候可以是倒置的. [题解] 我们将每个字符串倒置,用 ...
- POJ 3080 Blue Jeans(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=3080 [题目大意] 求k个串的最长公共子串,如果存在多个则输出字典序最小,如果长度小于3则判断查找失败. [题解] 将所有字符串通 ...
随机推荐
- Ecplise下设置jQuery和ExtJs自动提示
Spket 1.6.23下载: http://yunpan.cn/cjJYmEcMFIuuN 访问密码 5642 ext jsb下载:http://yunpan.cn/cjJYR7ZTzibQn ...
- Hibernate 懒加载 错误----no session
错误: unable to evaluate the expression Method threw 'org.hibernate.LazyInitializa org.hibernate.LazyI ...
- 粉刷匠(bzoj 1296)
Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个 ...
- vivo面试经验4(linux基本操作,最基本,必须得会!!)
操作linux通过xshell进行连接: 基本操作介绍 1.shutdown -h 关机 shutdown -r 重启 2.mkdir aaa 新建目录aaa rmdir aaa 删除目录aaa 3. ...
- Nios II 中的缓存和内存数据的读写
nios 使用地址中31bit来表示访问是否bypass cache.如果bit 31=0 表示不bypass cache,即使用cache里的数据:如果bit 31=1表示bypass cache, ...
- Opencv 学习笔记之——鼠标,进度条操作
Opencv中提供一个鼠标调用的函数,SetMouseCallback()函数,它配合一个回调函数来实现鼠标操作的功能. 首先看一下SetMouseCallback的函数原型: c++: void ...
- android 使用开源库zxing生成二维码,扫描二维码【转】
转自:http://blog.csdn.net/qq_16064871/article/details/52422723 zxing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库 ...
- Java 5大内存区域和对象的创建过程
1.Java运行时数据区 方法区,堆线程共享.虚拟机栈,本地方法栈和程序计数器线程私有. 2.程序计数器(PC计数器) 占用较小的一块内存空间,当执行Java方法时记录正在执行的虚拟机字节码指令地址, ...
- Selenium2+python自动化24-js处理富文本(带iframe)【转载】
前言 上一篇Selenium2+python自动化23-富文本(自动发帖)解决了富文本上iframe问题,其实没什么特别之处,主要是iframe的切换,本篇讲解通过js的方法处理富文本上iframe的 ...
- java的maven项目(一)
Maven项目管理工具 Svn + eclipse 约等于 maven量级 1 Maven的简介 1.1 什么是maven 是apache下的一个开源项目,是纯java开发,并 ...