题目

Source

http://acm.hdu.edu.cn/showproblem.php?pid=4080

Description

Dr. Ellie Arroway has established contact with an extraterrestrial civilization. However, all efforts to decode their messages have failed so far because, as luck would have it, they have stumbled upon a race of stuttering aliens! Her team has found out that, in every long enough message, the most important words appear repeated a certain number of times as a sequence of consecutive characters, even in the middle of other words. Furthermore, sometimes they use contractions in an obscure manner. For example, if they need to say bab twice, they might just send the message babab, which has been abbreviated because the second b of the first word can be reused as the first b of the second one.
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).

Input

The 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.

Output

Print 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的子串的最长长度以及出现在最右边的位置。

经典的后缀数组题目吧,二分长度,height分组判定长度是否成立。。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 44444 int wa[MAXN],wb[MAXN],wv[MAXN],ws[MAXN];
int cmp(int *r,int a,int b,int l){
return r[a]==r[b] && r[a+l]==r[b+l];
}
int sa[MAXN],rnk[MAXN],height[MAXN];
void SA(int *r,int n,int m){
int *x=wa,*y=wb; for(int i=0; i<m; ++i) ws[i]=0;
for(int i=0; i<n; ++i) ++ws[x[i]=r[i]];
for(int i=1; i<m; ++i) ws[i]+=ws[i-1];
for(int i=n-1; i>=0; --i) sa[--ws[x[i]]]=i; int p=1;
for(int j=1; p<n; j<<=1,m=p){
p=0;
for(int i=n-j; i<n; ++i) y[p++]=i;
for(int i=0; i<n; ++i) if(sa[i]>=j) y[p++]=sa[i]-j;
for(int i=0; i<n; ++i) wv[i]=x[y[i]];
for(int i=0; i<m; ++i) ws[i]=0;
for(int i=0; i<n; ++i) ++ws[wv[i]];
for(int i=1; i<m; ++i) ws[i]+=ws[i-1];
for(int i=n-1; i>=0; --i) sa[--ws[wv[i]]]=y[i];
swap(x,y); x[sa[0]]=0; p=1;
for(int i=1; i<n; ++i) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
} for(int i=1; i<n; ++i) rnk[sa[i]]=i;
int k=0;
for(int i=0; i<n-1; height[rnk[i++]]=k){
if(k) --k;
for(int j=sa[rnk[i]-1]; r[i+k]==r[j+k]; ++k);
}
} char str[MAXN];
int n,m,a[MAXN]; bool isOK(int len){
int left=-1,right,mx=0;
for(int i=2; i<=n; ++i){
if(height[i]>=len){
if(left==-1) left=i-1;
right=i;
}else{
left=-1;
}
if(left!=-1) mx=max(mx,right-left+1);
}
return mx>=m;
} int getRightMost(int len){
int left=-1,right,mx=0,tmp=0;
for(int i=2; i<=n; ++i){
if(height[i]>=len){
if(left==-1) left=i-1;
right=i;
tmp=max(tmp,max(sa[i-1],sa[i]));
}else{
left=-1;
tmp=0;
}
if(left!=-1){
if(right-left+1>=m) mx=max(mx,tmp);
}
}
return mx;
} int main(){
while(scanf("%d",&m)==1 && m){
scanf("%s",str);
n=strlen(str);
if(m==1){
printf("%d %d\n",n,0);
continue;
}
for(int i=0; i<n; ++i){
a[i]=str[i]-'a'+1;
}
a[n]=0;
SA(a,n+1,28);
int l=0,r=MAXN;
while(l<r){
int mid=l+r+1>>1;
if(isOK(mid)) l=mid;
else r=mid-1;
}
if(l==0){
puts("none");
continue;
}
printf("%d %d\n",l,getRightMost(l));
}
return 0;
}

HDU4080 Stammering Aliens(二分 + 后缀数组)的更多相关文章

  1. BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)

    求多串的最长公共字串. 法1: 二分长度+hash 传送门 法2: 二分+后缀数组 传送门 法3: 后缀自动机 拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再 ...

  2. UVALive - 4513 Stammering Aliens ——(hash+二分 || 后缀数组加二分)

    题意:找一个出现了m次的最长子串,以及这时的最右的位置. hash的话代码还是比较好写的,,但是时间比SA多很多.. #include <stdio.h> #include <alg ...

  3. HDU4080Stammering Aliens(后缀数组+二分)

    However, all efforts to decode their messages have failed so far because, as luck would have it, the ...

  4. HDU5853 Jong Hyok and String(二分 + 后缀数组)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5853 Description Jong Hyok loves strings. One da ...

  5. 【HDU 5030】Rabbit's String (二分+后缀数组)

    Rabbit's String Problem Description Long long ago, there lived a lot of rabbits in the forest. One d ...

  6. POJ1743 Musical Theme(二分+后缀数组)

    题目大概是给n个数组成的串,求是否有多个“相似”且不重叠的子串的长度大于等于5,两个子串相似当且仅当长度相等且每一位的数字差都相等. 这题是传说中楼教主男人八题之一,虽然已经是用后缀数组解决不可重叠最 ...

  7. POJ1226 Substrings(二分+后缀数组)

    题意:给n个字符串,求最长的子串,满足它或它的逆置出现在所有的n个字符串中. 把n个字符串及其它们的逆置拼接,中间用不同字符隔开,并记录suffix(i)是属于哪个字符串的: 跑后缀数组计算heigh ...

  8. POJ3294 Life Forms(二分+后缀数组)

    给n个字符串,求最长的多于n/2个字符串的公共子串. 依然是二分判定+height分组. 把这n个字符串连接,中间用不同字符隔开,跑后缀数组计算出height: 二分要求的子串长度,判断是否满足:he ...

  9. 140. 后缀数组(hash + 二分 / 后缀数组)

    题目链接 : https://www.acwing.com/problem/content/description/142/ Hash + 二分 #include <bits/stdc++.h& ...

随机推荐

  1. [Android Pro] Android 性能分析工具dumpsys的使用

    reference to : http://www.open-open.com/lib/view/open1405061994872.html Android提供的dumpsys工具可以用于查看感兴趣 ...

  2. 统计 F-test 和 T-test

    1 显著性差异 如果样本足够大,很容易有显著性差异.样本小,要有显著性差异很难. y是因变量,x是自变量 2 F-test与T-test Ftest也称ANOVA,是用来检测一个y下的不同level的 ...

  3. python 获取控制台输入

    python想从控制台获取输入的的函数有两个一个是raw_input,一个是input. 这两个函数的区别是input获取的时候会精确到类型,假设输入的是1,那么获取的就是int型的变量,如果想输入字 ...

  4. 绿色通道(codevs 3342)

    题目描述 Description <思远高考绿色通道>(Green Passage, GP)是唐山一中常用的练习册之一,其题量之大深受lsz等许多oiers的痛恨,其中又以数学绿色通道为最 ...

  5. zmq-ios framwork

    1.附件见zeromq-ios.framework百度网盘/iOS/zmq 2.zeromq-ios.framework解压拖进工程文件 3.objc-zmq见百度网盘/iOS/zmq 4.objc- ...

  6. 三、jQuery--jQuery基础--jQuery基础课程--第10章 jQuery UI型插件

    1.拖曳插件——draggable 拖曳插件draggable的功能是拖动被绑定的元素,当这个jQuery UI插件与元素绑定后,可以通过调用draggable()方法,实现各种拖曳元素的效果,调用格 ...

  7. 游戏主循环(Game Loop)

    游戏主循环是游戏的心跳,一般使用while循环进行主动刷新. 一次循环由获取用户输入.更新游戏状态.处理AI.播放音乐和绘制画面组成. 这些行为可以分成两类: update_game(); // 更新 ...

  8. 如何调试SSIS包之跟踪变量赋值

    在SSIS开发工具SQL Server Data Tools中提供了调试功能,可以让我们方便的跟踪参数赋值或者数据流条数.本文主要介绍了如何使用SSDT的调试功能. Part A: Script ta ...

  9. 命令行登陆Oracle(包括远程登陆)

    本方法适用于在cmd命令行窗口以及pl/sql登陆Oracle下登录本机或者远程Oracle. 1.首先保证在当前主机上设置了ORACLE_HOME环境变量:     例如:ORACLE_HOME=D ...

  10. <转>ORA-12154: TNS: 无法解析指定的连接标识符

    相信作为ORACLE数据库的开发人员没有少碰到“ORA-12154: TNS: 无法解析指定的连接标识符”,今天我也又碰到了类似的情况,将我的解决方法进行小结,希望能对碰到同样问题的友人们提供帮助. ...