在这道题上学会了两种方法解决。一种是用哈希lcp法,另一种用后缀数组求解。
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 40000, 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 possible starting position of such a substring.
Sample Input
3
baaaababababbababbab
11
baaaababababbababbab
3
cccccc
0
Sample Output
5 12 none 42

第一种后缀数组求解,

//
//  main.cpp
//  口吃的外星人(后缀数组+公共前缀)
//
//  Created by zhoujl on 15/11/7.
//  Copyright (c) 2015年 zhoujl. All rights reserved.
//
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
using namespace std;
#define cls(a, n) memset(a, n, sizeof(a))
#define REP(i, n) rep(i, 0, n)
#define inf 0x7ffffffff
#define rep(i, l, n) for (int i = l; i < n; i++)
typedef long long LL;
const int maxn = 400*100+10;
struct suffix {int sa[maxn], t1[maxn], t2[maxn], c[maxn], height[maxn], d[maxn][50], rank[maxn];char s[maxn];int n;void build_sa(int m) {int * x = t1, *y= t2;REP(i, m) c[i] = 0;REP(i, n) c[x[i] = (s[i]-'a' + 1)]++;rep(i, 1 ,m) c[i] += c[i-1];for (int i = n-1; i >= 0; i--) sa[--c[x[i]]] = i;for (int j = 1;  j < n; j <<= 1) {int p = 0, k;for (k = n-j; k < n; k++)y[p++] = k;rep(i, 0, n) {if (sa[i] - j >= 0)y[p++] = sa[i] - j;}REP(i, m) c[i] = 0;REP(i, n) c[x[y[i]]]++;rep(i, 1 ,m) c[i] += c[i-1];for (int i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];swap(x, y);p = 1;x[sa[0]] = 0;rep(i, 1, n) {if (y[sa[i]] == y[sa[i-1]] && y[sa[i]+j] == y[sa[i-1]+j]) {x[sa[i]] = p - 1;} else {x[sa[i]] = p++;}}if (p >= n)break;m = p;}}void build_ht() {int k = 0;rep(i, 1, n+1) rank[sa[i]] = i;rep(i, 0, n) {if (k) k--;while (rank[i] && s[i+k] == s[sa[rank[i]-1]+k]) {k++;}height[rank[i]] = k;// height[]的合法范围为 1-N, 其中0是结尾加入的字符}}void RMQ_init() {int i, j;rep(i, 1, n+1)d[i][0] = height[i];for (i = 1; (1<<i) <= n; i++) {for (j = 1; j+(1<<i)-1 <= n; j++) {d[j][i] = min(d[j][i-1] , d[j+(1<<(i-1))][i-1]);}}}int RMQ(int l, int r) {int k = 0;while ((1<<(k+1)) <= r-l+1) k++;return min(d[l][k], d[r-(1<<k)+1][k]);}void clear() {}
};
suffix tree;
int main() {int m;while (scanf("%d", &m) && m != 0) {scanf("%s", tree.s);tree.n = strlen(tree.s); tree.clear();tree.s[tree.n] = 'a'-1;tree.n++;//注意区分此处为n+1,因为添加了一个结尾字符用于区别比较tree.build_sa(27);tree.n--;tree.build_ht();tree.RMQ_init();int maxl = 0;int pos = 0;if (m == 1) {printf("%d %d\n", tree.n, 0);continue;}for (int i = tree.n-1; i >= 0; i--) {if (tree.rank[i]+m-1 <= tree.n) {int max2 = tree.RMQ(tree.rank[i]+1, tree.rank[i]+m-1);if (maxl < max2) {maxl = max2;pos = i;int p = tree.rank[i]+m-1;while (p >= tree.rank[i]+1) {if (tree.sa[p] > pos)pos = tree.sa[p];p--;}} else if (maxl == max2) {pos = max(pos, i);int p = tree.rank[i]+m-1;while (p >= tree.rank[i]+1) {if (tree.sa[p] > pos)pos = tree.sa[p];p--;}}}}if (maxl) {printf("%d %d\n", maxl, pos);} else {printf("none\n");}}return 0;
}

第二种哈希lcp算法求解

为每个后缀计算一个哈希值,满足递推式:H[i] = H[i-1]x + s[i],其中,H[n] = 0

对于长度为L的字符串,定义它的Hash值为Hash[i,L] = H[i] - H[i+L] x ^ L,其中x值是任意的。H和Hash数组保存成unsigned long long

//
//  main.cpp
//  口吃的外星人(哈希值的lcp算法)
//
//  Created by zhoujl on 15/11/4.
//  Copyright (c) 2015年 zhoujl. All rights reserved.
//
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
typedef long long LL;
#define cls(a, n) memset(a, n, sizeof(a))
#define rep(i, l, n) for (int i = l; i < n; i++)
const int maxn = 400010;
const int x = 123;
LL h[maxn], xp[maxn], hasha[maxn];
int ranka[maxn];
char s[maxn];
int m, pos, n;
int cmp(int a, int b) {return (hasha[a] < hasha[b]) ||(hasha[a] == hasha[b] && a < b);
}
int possible(int L) {int c = 0;pos = -1;rep(i, 0, n-L+1) {ranka[i] = i;hasha[i] = h[i] - h[i+L]*xp[L];}sort(ranka, ranka+n-L+1, cmp);rep(i, 0, n-L+1) {if (i == 0 || hasha[ranka[i]] != hasha[ranka[i-1]]) c = 0;if (++c >= m)pos = max(pos, ranka[i]);}return pos >= 0;
}
int main() {while (scanf("%d", &m) == 1 &&m != 0) {scanf("%s", s);n = strlen(s);h[n] = 0;for (int i = n-1; i >= 0; i--) {h[i] = h[i+1]*x + s[i]-'a';}xp[0] = 1;rep(i, 1, n) xp[i] = xp[i-1] * x;if (!possible(1)) {printf("none\n");} else {int L = 1, R = n+1;while (R - L > 1) {int M = (R+L) / 2;if (possible(M)) L = M;else R = M;}possible(L);printf("%d %d\n", L, pos);}}return 0;
}

LA 4513 Stammering Aliens相关推荐

  1. Hash(LCP) || 后缀数组 LA 4513 Stammering Aliens

    题目传送门 题意:训练指南P225 分析:二分寻找长度,用hash值来比较长度为L的字串是否相等. #include <bits/stdc++.h> using namespace std ...

  2. UVALive 4513 Stammering Aliens

    题意: 给定一个数m,一个字符串s,求s中至少出现m次的最长子串长度,并输出位置最靠后的对应子串的下标:串长度<=40000 分析: 构造后缀数组: 先二分答案mid,然后检查高度数组(LCP) ...

  3. Stammering Aliens

    2.Stammering Aliens (aliens.cpp) 有一个口吃的外星人,说的话里包含很多重复的字符串,比如babab包含两个bab.给定这个外星人说的一句话,找出至少出现m次的最长字符串 ...

  4. HDU4080【Stammering Aliens】(字符串哈希、二分法)

    •题目地址HDU4080[Stammering Aliens] •题目描述 • Ellie Arroway博士与一个外星文明建立了联系.然而,所有破解外星人讯息的努力都失败了,因为他们遇上了一群口吃的 ...

  5. HDU4080 Stammering Aliens(二分 + 后缀数组)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4080 Description Dr. Ellie Arroway has establish ...

  6. hdu-4080 Stammering Aliens 字符串hash 模板题

    http://acm.hdu.edu.cn/showproblem.php?pid=4080 求出现次数大于等于n的最长串. #include<iostream> #include< ...

  7. UVa 12206 (字符串哈希) Stammering Aliens

    体验了一把字符串Hash的做法,感觉Hash这种人品算法好神奇. 也许这道题的正解是后缀数组,但Hash做法的优势就是编码复杂度大大降低. 1 #include <cstdio> 2 #i ...

  8. 题解 UVA12206 【Stammering Aliens】

    终于A了这道题啊(坑啊) 教练说:这道题不能用map吧,复杂度不一个O(nlogn)吗 于是我就一直想不出来,然后看题解代码,一看就是map... 所以我就在想,那复杂度是不是也不是O(nlogn)呢 ...

  9. 《题目与解读》红书 训练笔记目录《ACM国际大学生程序设计竞赛题目与解读》

    虽然2012年出版的老书了,但是是由三次世界冠军的上海交大ACM队出版的书籍,选择的题目是ACM经典中的经典,书中有非常详细的题解,可以学到很多东西,值得一刷. 目录 第一部分 第一章 数学 1.1 ...

最新文章

  1. HashTable原理与实现
  2. 高级转录组分析和R数据可视化第11期(报名线上课还可免费参加线下课2020.6)
  3. 你想使用自己编译的内核进行工作吗?
  4. 【项目】itdage-java获取天气和发短信
  5. northwind中文 for mysql_学习心得 | PHP与mysql通信的若干问题
  6. SMT精密电阻对照表
  7. mysql5.7.17配置_mysql-5.7.17-winx64的安装配置
  8. CMakeList.txt的简介
  9. 计算机c盘是软盘吗,涨知识:为什么电脑都是从C盘开始,没有A和B?
  10. python中gm11_python实现灰色预测模型(GM11)——以预测股票收盘价为例
  11. 系统学习语义分割文章推荐以及顺序
  12. 中国社会为何多犬儒?
  13. 网恋背后的骗局:那些被宰杀掉的猪!必看!
  14. Linux内存访问(Liunx驱动3)
  15. 计算机能直接执行的语言程序是,计算机能够直接执行的程序是什么语言
  16. c++ stl栈容器stack用法介绍
  17. C#工控上位机开发-->1、C#快速编程入门
  18. 一键关闭windows防火墙_win7系统怎么一键关闭危险端口怎么办【操作方法】
  19. 实现灰度化 Grayscale(灰度)的实现
  20. 一个好的想法在你的投资组合

热门文章

  1. Halcon模板匹配定位跟随找圆
  2. sql查询语句--wher后不能放聚集函数的解决办法
  3. R2S:年轻人的第一台软路由
  4. 大概率思维《The House Advantage》
  5. 122. 买卖股票的最佳时机 II
  6. 计算机英语kbc,计算机英语词汇(附;翻译).doc
  7. 【QT开发笔记-基础篇】| 第五章 绘图QPainter | 5.11 路径
  8. 关于Altium designer中45°、90°及圆弧线的切换
  9. 板式家具生产工艺流程是怎样
  10. mysql 查询总数时条件_SQL查询数据库中符合条件的记录的总数