注意:对整型数组求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的更多相关文章

  1. BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案

    BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单 ...

  2. Poj 1743 Musical Theme(后缀数组+二分答案)

    Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...

  3. Poj 3261 Milk Patterns(后缀数组+二分答案)

    Milk Patterns Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk g ...

  4. POJ3294--Life Forms 后缀数组+二分答案 大于k个字符串的最长公共子串

                                                                              Life Forms Time Limit: 500 ...

  5. SPOJ 220 Relevant Phrases of Annihilation(后缀数组+二分答案)

    [题目链接] http://www.spoj.pl/problems/PHRASES/ [题目大意] 求在每个字符串中出现至少两次的最长的子串 [题解] 注意到这么几个关键点:最长,至少两次,每个字符 ...

  6. POJ 3261 Milk Patterns(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=3261 [题目大意] 求最长可允许重叠的出现次数不小于k的子串. [题解] 对原串做一遍后缀数组,二分子串长度x,将前缀相同长度超过 ...

  7. POJ 3294 Life Forms(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=3294 [题目大意] 求出在至少在一半字符串中出现的最长子串. 如果有多个符合的答案,请按照字典序输出. [题解] 将所有的字符串通 ...

  8. POJ 1743 Musical Theme(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=1743 [题目大意] 给出一首曲子的曲谱,上面的音符用不大于88的数字表示, 现在请你确定它主旋律的长度,主旋律指的是出现超过一次, ...

  9. POJ 1226 Substrings(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=1226 [题目大意] 求在每个给出字符串中出现的最长子串的长度,字符串在出现的时候可以是倒置的. [题解] 我们将每个字符串倒置,用 ...

  10. POJ 3080 Blue Jeans(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=3080 [题目大意] 求k个串的最长公共子串,如果存在多个则输出字典序最小,如果长度小于3则判断查找失败. [题解] 将所有字符串通 ...

随机推荐

  1. bzoj 2304 [Apio2011]寻路 Dij+模拟+恶心建图

    [Apio2011]寻路 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 624  Solved: 193[Submit][Status][Discus ...

  2. ShareSDK入门指南:Android 10分钟快速集成

    ShareSDK 官方已提供Android 快速集成教程,以官方教程为参考,本文重点指导大家在集成中遇到的问题. Android 快速集成官方教程:http://wiki.mob.com/Androi ...

  3. linux网络编程系列-TCP/IP模型

    ### OSI:open system interconnection ### 开放系统互联网模型是由ISO国际标准化组织定义的网络分层模型,共七层 1. 物理层:物理定义了所有电子及物理设备的规范, ...

  4. 入门级:GitHub和Git超超超详细使用教程!

    GitHub和Git入门 考虑到大家以前可能对版本控制工具和Linux命令行工具都不了解,我写了一个简单的博客来让大家学会入门使用方法. GitHub的简单使用 第一步 创建GitHub账号 1. 打 ...

  5. MVC 自定义HtmlHelper帮助类型之分页

    方法一: 在项目中增加App_Code文件夹,新增一个MyHtmlper.cshtml视图文件 写入代码: @helper Pagger(int pageIndex, int pageCount) { ...

  6. Visual Studio Code 配置C/C++环境

    0. 前言 VS Code 是微软发布一款跨平台的源代码编辑器,其拥有强大的功能和丰富的扩展,使之能适合编写许多语言. 本文面向初学者(但不是纯小白),分享一点我配置C/C++的经验. 本文所有内容均 ...

  7. linux编译动态库 fPIC作用

    在生成动态库时,常常习惯性的加上fPIC选项,fPIC有什么作用和意义,加不加有什么区别,这里做下小结: fPIC的全称是 Position Independent Code, 用于生成位置无关代码. ...

  8. 51nodeE 斜率最大

    题目传送门 这道题只要证明最佳解一定在相邻两个点之间的好啦 这个自己证一证就okay啦 而且我发现n方的算法可以过耶... #include<cstdio> #include<cst ...

  9. [BZOJ1036][ZJOI2008]树的统计Count 解题报告|树链剖分

    树链剖分 简单来说就是数据结构在树上的应用.常用的为线段树splay等.(可现在splay还不会敲囧) 重链剖分: 将树上的边分成轻链和重链. 重边为每个节点到它子树最大的儿子的边,其余为轻边. 设( ...

  10. GridPanel 带头和锁定列共存

    该功能还存在很多BUG,仅供参考 Ext.net.ResourceMgr.load([{ url: _HOST + "Js/OverwriteExtjs/LockingHeaderGroup ...