HDU4080Stammering Aliens(后缀数组+二分)
Thus, the message contains possibly overlapping repetitions of the same words over and over again. As a result, Ellie turns to you, S.R. Hadden, for help in identifying the gist of the message.
Given an integer m, and a string s, representing the message, your task is to find the longest substring of s that appears at least m times. For example, in the message baaaababababbababbab, the length-5 word babab is contained 3 times, namely at positions 5, 7 and 12 (where indices start at zero). No substring appearing 3 or more times is longer (see the first example from the sample input). On the other hand, no substring appears 11 times or more (see example 2). In case there are several solutions, the substring with the rightmost occurrence is preferred (see example 3).
InputThe input contains several test cases. Each test case consists of a line with an integer m (m >= 1), the minimum number of repetitions, followed by a line containing a string s of length between m and 40 000, inclusive. All characters in s are lowercase characters from "a" to "z". The last test case is denoted by m = 0 and must not be processed.
OutputPrint one line of output for each test case. If there is no solution, output none; otherwise, print two integers in a line, separated by a space. The first integer denotes the maximum length of a substring appearing at least m times; the second integer gives the rightmost starting position of this substring.
Sample Input
3
baaaababababbababbab
11
baaaababababbababbab
3
cccccc
0
Sample Output
5 12
none
4 2
题意:
求字符串里面出现的子序列中出现超过m次的最长子序列(可交叉),没有输出none,有则输出长度,和最后一次出现的位置。
思路:
求出后缀数组,二分长度,得到长度,至于最后一次的位置,需要把每个位置枚举一下,即大于Mid的ht[i],对应着的sa[i],和sa[i-1]。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
const int maxn=;
char ch[maxn]; int m;
int max(int x,int y){if(x>y) return x;return y;}
struct SA
{
int Rank[maxn],sa[maxn],tsa[maxn],cntA[maxn],cntB[maxn],A[maxn],B[maxn];
int ht[maxn],N;
void get_sa()
{
N=strlen(ch+);
for(int i=;i<=;i++) cntA[i]=;
for(int i=;i<=N;i++) cntA[ch[i]]++;
for(int i=;i<=;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-]]+(ch[sa[i]]==ch[sa[i-]]?:);
for(int l=;Rank[sa[N]]<N;l<<=){
for(int i=;i<=N;i++) cntA[i]=cntB[i]=;
for(int i=;i<=N;i++) cntA[A[i]=Rank[i]]++;
for(int i=;i<=N;i++) cntB[B[i]=i+l<=N?Rank[i+l]:]++;
for(int i=;i<=N;i++) cntA[i]+=cntA[i-],cntB[i]+=cntB[i-];
for(int i=N;i>=;i--) tsa[cntB[B[i]]--]=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-]]+(A[sa[i]]==A[sa[i-]]&&B[sa[i]]==B[sa[i-]]?:);
}
}
void get_ht()
{
for(int i=,j=;i<=N;i++){
if(j) j--;
while(ch[i+j]==ch[sa[Rank[i]-]+j]) j++;
ht[Rank[i]]=j;
}
}
int check(int L)
{
int cnt=,tmppos=,pos=;
for(int i=;i<=N;i++){
if(ht[i]<L) cnt=,tmppos=;
else cnt++,tmppos=max(tmppos,max(sa[i],sa[i-]));
if(cnt>=m) pos=max(tmppos,pos);
} return pos;
}
void solve()
{
//for(int i=1;i<=N;i++) printf("%d ",sa[i]);printf("\n");
//for(int i=1;i<=N;i++) printf("%d ",ht[i]);printf("\n");
int L=,R=N,ans=,tmp,anspos=;
while(L<=R){
int Mid=(L+R)>>;
tmp=check(Mid);
if(tmp) {
ans=Mid;anspos=tmp; L=Mid+;
} else R=Mid-;
}
if(ans==) printf("none\n");
else printf("%d %d\n",ans,anspos-);
}
}Sa;
int main()
{
int i,j,k;
while(~scanf("%d",&m)&&m){
scanf("%s",ch+);
if(m==){
printf("%d 0\n",strlen(ch+));
continue;
}
Sa.get_sa();
Sa.get_ht();
Sa.solve();
} return ;
}
HDU4080Stammering Aliens(后缀数组+二分)的更多相关文章
- BZOJ 3230: 相似子串( RMQ + 后缀数组 + 二分 )
二分查找求出k大串, 然后正反做后缀数组, RMQ求LCP, 时间复杂度O(NlogN+logN) -------------------------------------------------- ...
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单 ...
- 【bzoj4310】跳蚤 后缀数组+二分
题目描述 很久很久以前,森林里住着一群跳蚤.一天,跳蚤国王得到了一个神秘的字符串,它想进行研究. 首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最大的那一个 ...
- BZOJ 1717 [USACO06DEC] Milk Patterns (后缀数组+二分)
题目大意:求可重叠的相同子串数量至少是K的子串最长长度 洛谷传送门 依然是后缀数组+二分,先用后缀数组处理出height 每次二分出一个长度x,然后去验证,在排序的后缀串集合里,有没有连续数量多于K个 ...
- POJ 1743 [USACO5.1] Musical Theme (后缀数组+二分)
洛谷P2743传送门 题目大意:给你一个序列,求其中最长的一对相似等长子串 一对合法的相似子串被定义为: 1.任意一个子串长度都大于等于5 2.不能有重叠部分 3.其中一个子串可以在全部+/-某个值后 ...
- 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 ...
- Uva12206 Stammering Aliens 后缀数组&&Hash
Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all effort ...
- UVA 12206 - Stammering Aliens(后缀数组)
UVA 12206 - Stammering Aliens 题目链接 题意:给定一个序列,求出出现次数大于m,长度最长的子串的最大下标 思路:后缀数组.搞出height数组后,利用二分去查找就可以 这 ...
随机推荐
- leetCode 83.Remove Duplicates from Sorted List(删除排序链表的反复) 解题思路和方法
Given a sorted linked list, delete all duplicates such that each element appear only once. For examp ...
- php设计模式中的类型安全 指--只接受特定的对象 ---以避免发生错误
在百度百科中---类型安全代码指访问被授权可以访问的内存位置
- 导入MySQL测试数据库employee报错
导入MySQL测试数据库employee 报错 下载地址:https://launchpad.net/test-db/ 上传解压: [root@001 ~]# tar xf employees_db- ...
- android WebView详细使用方法(转)
1.最全面的Android Webview详解 2.最全面总结 Android WebView与 JS 的交互方式 3.你不知道的 Android WebView 使用漏洞 如果想保证登录状态,就插入 ...
- python 基础 6.2 raise 关键字使用
一. raise 关键字 raise 用来触发异常 语法如下: raise[Exception [,args [,traceback]]] 语句中Exception 是异常 ...
- EasyPlayerPro(Windows)流媒体播放器功能介绍及应用场景
EasyPLyerPro(Windows)经过为期一个月的开发已经基本完成,虽然目前仍存在一些小问题,但是总体功能还是趋于比较稳定和强大的,下面对其功能和应用场景做简要介绍. 一.EasyPlayer ...
- Asp.net MVC3中全局图片防盗链
怎么样在Asp.Net MVC3中做到全局图片防盗链?如果熟悉Asp.Net的页面生命周期,相信解决这个问题应该很容易.下面就演示一下如何去做? 一.首先是全局的,我们肯定要在Global.asax文 ...
- windows下安装mysql 开机启动
1 下载地址 http://dev.mysql.com/downloads/installer/ 2 下载版本 mysql community server 5.7.x 这个版本是一个傻瓜版本,设置r ...
- CentOS、乌班图设置固定静态IP
CentOS.乌班图设置固定静态IP 一.centOS 1.编辑 ifcfg-eth0 文件 # vim /etc/sysconfig/network-scripts/ifcfg-eth0 2,在文件 ...
- php总结4——数组的定义及函数、冒泡排序
4.1 数组的定义 数组:变量存储的有序序列. 索引数组:下标为数字的数组. $数组名称(下标) 下标从0开始的数字. 直接定义: $arr[0]=123; $arr[1]="chi ...