题目

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分组判定长度是否成立。。

代码

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. #define MAXN 44444
  6.  
  7. int wa[MAXN],wb[MAXN],wv[MAXN],ws[MAXN];
  8. int cmp(int *r,int a,int b,int l){
  9. return r[a]==r[b] && r[a+l]==r[b+l];
  10. }
  11. int sa[MAXN],rnk[MAXN],height[MAXN];
  12. void SA(int *r,int n,int m){
  13. int *x=wa,*y=wb;
  14.  
  15. for(int i=0; i<m; ++i) ws[i]=0;
  16. for(int i=0; i<n; ++i) ++ws[x[i]=r[i]];
  17. for(int i=1; i<m; ++i) ws[i]+=ws[i-1];
  18. for(int i=n-1; i>=0; --i) sa[--ws[x[i]]]=i;
  19.  
  20. int p=1;
  21. for(int j=1; p<n; j<<=1,m=p){
  22. p=0;
  23. for(int i=n-j; i<n; ++i) y[p++]=i;
  24. for(int i=0; i<n; ++i) if(sa[i]>=j) y[p++]=sa[i]-j;
  25. for(int i=0; i<n; ++i) wv[i]=x[y[i]];
  26. for(int i=0; i<m; ++i) ws[i]=0;
  27. for(int i=0; i<n; ++i) ++ws[wv[i]];
  28. for(int i=1; i<m; ++i) ws[i]+=ws[i-1];
  29. for(int i=n-1; i>=0; --i) sa[--ws[wv[i]]]=y[i];
  30. swap(x,y); x[sa[0]]=0; p=1;
  31. for(int i=1; i<n; ++i) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
  32. }
  33.  
  34. for(int i=1; i<n; ++i) rnk[sa[i]]=i;
  35. int k=0;
  36. for(int i=0; i<n-1; height[rnk[i++]]=k){
  37. if(k) --k;
  38. for(int j=sa[rnk[i]-1]; r[i+k]==r[j+k]; ++k);
  39. }
  40. }
  41.  
  42. char str[MAXN];
  43. int n,m,a[MAXN];
  44.  
  45. bool isOK(int len){
  46. int left=-1,right,mx=0;
  47. for(int i=2; i<=n; ++i){
  48. if(height[i]>=len){
  49. if(left==-1) left=i-1;
  50. right=i;
  51. }else{
  52. left=-1;
  53. }
  54. if(left!=-1) mx=max(mx,right-left+1);
  55. }
  56. return mx>=m;
  57. }
  58.  
  59. int getRightMost(int len){
  60. int left=-1,right,mx=0,tmp=0;
  61. for(int i=2; i<=n; ++i){
  62. if(height[i]>=len){
  63. if(left==-1) left=i-1;
  64. right=i;
  65. tmp=max(tmp,max(sa[i-1],sa[i]));
  66. }else{
  67. left=-1;
  68. tmp=0;
  69. }
  70. if(left!=-1){
  71. if(right-left+1>=m) mx=max(mx,tmp);
  72. }
  73. }
  74. return mx;
  75. }
  76.  
  77. int main(){
  78. while(scanf("%d",&m)==1 && m){
  79. scanf("%s",str);
  80. n=strlen(str);
  81. if(m==1){
  82. printf("%d %d\n",n,0);
  83. continue;
  84. }
  85. for(int i=0; i<n; ++i){
  86. a[i]=str[i]-'a'+1;
  87. }
  88. a[n]=0;
  89. SA(a,n+1,28);
  90. int l=0,r=MAXN;
  91. while(l<r){
  92. int mid=l+r+1>>1;
  93. if(isOK(mid)) l=mid;
  94. else r=mid-1;
  95. }
  96. if(l==0){
  97. puts("none");
  98. continue;
  99. }
  100. printf("%d %d\n",l,getRightMost(l));
  101. }
  102. return 0;
  103. }

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. ios wax热更新之安装wax(xcode7.3.1)

    通过Finder浏览到你保存该项目的文件夹.创建三个新的文件夹:wax.scripts和Classes. 第一:首先,下载源代码的压缩包.Wax放在GitHub上(https://github.com ...

  2. oracle 的PACKAGE恢复过程

    SELECT obj# FROM obj$ AS OF TIMESTAMP TO_TIMESTAMP('2016-06-30', 'YYYY-MM-DD') WHERE NAME = 'PFWZ_AP ...

  3. ld returned 1 exit status"的解决办法

    在Linux下创建线程时,编译时会出现下面的错误,[root@linuxserver 807]# gcc -o 22 22.c/tmp/cc21HcoW.o(.text+0x4c): In funct ...

  4. max file descriptors [4096] for elasticsearch process likely too low, increase to at least [65536]

    在/etc/syscurity/limits.conf 加入以下两行: elastic hard nofile 65536 elastic soft nofile  65536 #备注:elastic ...

  5. 同一内网不能网段ping 不通

    [root@NB sysconfig]# route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use ...

  6. 数据结构和算法 – 12.高级查找算法(下)

    哈希(散列)技术既是一种存储方法,也是一种查找方法.然而它与线性表.树.图等结构不同的是,前面几种结构,数据元素之间都存在某种逻辑关系,可以用连线图示表示出来,而哈希技术的记录之间不存在什么逻辑关系, ...

  7. HTTPS的一些疑问解答

    PHP写的网站怎么用https访问,具体要怎样 这跟用什么语言写的网站没有关系,可以去申请个快速的SSL证书,一年也就几十块. 开启apache server的ssl,自己做个免费的ssl证书或者去申 ...

  8. PostgreSQL的时间/日期函数使用

    PostgreSQL的常用时间函数使用整理如下: 一.获取系统时间函数 1.1 获取当前完整时间 select now(); david=# select now(); now ----------- ...

  9. ImageSwitcher自定意效果+定时切换图片

    Activity实现 1 import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent; ...

  10. poj 2337 欧拉回路输出最小字典序路径 ***

    把26个小写字母当成点,每个单词就是一条边. 然后就是求欧拉路径. #include<cstdio> #include<iostream> #include<algori ...