博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Uva12206 Stammering Aliens 后缀数组&&Hash
阅读量:6685 次
发布时间:2019-06-25

本文共 6808 字,大约阅读时间需要 22 分钟。

  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 possible starting position of such a substring.

Sample Input

3

baaaababababbababbab

11

baaaababababbababbab

3

cccccc

0

Sample

Output

5 12

none

4 2

 

大白书原题,没事干用后缀数组实现一下

#include 
#include
#include
using namespace std;const int MAXN = 40000 + 10;/*const int x = 123;typedef unsigned long long ull;ull H[MAXN], xp[MAXN];ull hash[MAXN];int rank[MAXN];char s[MAXN];int n, m, pos;int cmp(const int& a, const int& b) { return hash[a] < hash[b] || (hash[a] == hash[b] && a < b);}int possible(int L) { int c = 0; pos = -1; for(int i = 0; i < n - L + 1; ++i) { rank[i] = i; hash[i] = H[i] - H[i + L] * xp[L]; } sort(rank, rank + n - L + 1, cmp); for(int i = 0; i < n - L + 1; ++i) { if(i == 0 || hash[ rank[i] ] != hash[ rank[i - 1] ]) c = 0; if(++c >= m) pos = max(pos, rank[i]); } return pos >= 0;}int main(){ freopen("in.txt", "r", stdin); freopen("out2.txt", "w", stdout); while(~scanf("%d", &m) && m) { 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; for(int i = 1; i <= n; ++i) xp[i] = xp[i - 1] * x; if(!possible(1)) puts("none"); else { int L = 1, R = n + 1; while(R - L > 1) { int M = (L + R) >> 1; if(possible(M)) L = M; else R = M; } possible(L); printf("%d %d\n", L, pos); } } return 0;}
Hash
#include 
#include
#include
using namespace std;const int maxn = 40000 + 10;int t1[maxn], t2[maxn], c[maxn];bool cmp(int *r, int a, int b, int l) { return r[a] == r[b] && r[a + l] == r[b + l];}void da(char str[], int sa[], int Rank[], int heigh[], int n, int m){ n++; int i, j, p, *x = t1, *y = t2; for(i = 0; i < m; ++i) c[i] = 0; for(i = 0; i < n; ++i) c[ x[i] = str[i] ]++; for(int i = 1; i < m; ++i) 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) { p = 0; for(i = n - j; i < n; ++i) y[p++] = i; for(i = 0; i < n; ++i) if(sa[i] >= j) y[p++] = sa[i] - j; for(i = 0; i < m; ++i) c[i] = 0; for(i = 0; i < n; ++i) c[x[y[i]]]++; for(i = 1; i < m; ++i) c[i] += c[i - 1]; for(i = n - 1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i]; swap(x, y); p = 1; x[ sa[0] ] = 0; for(i = 1; i < n; ++i) x[ sa[i] ] = cmp(y, sa[i - 1], sa[i], j) ? p - 1 : p++; if(p >= n) break; m = p; } int k = 0; n--; for(i = 0; i <= n; ++i) Rank[ sa[i] ] = i; for(i = 0; i < n; ++i) { if(k) k--; j = sa[Rank[i] - 1]; while(str[i + k] == str[j + k]) k++; heigh[ Rank[i] ] = k; }}int Rank[maxn], heigh[maxn], sa[maxn];char s[maxn];void out(int n) { puts("Rank[]"); ///Rank数组的有效范围是0~n-1, 值是1~n for(int i = 0; i <= n; ++i) printf("%d ", Rank[i]); puts("sa[]"); ///sa数组的有效范围是1~n,值是0~n-1 for(int i = 0; i <= n; ++i) printf("%d ", sa[i]); puts("heigh[]"); ///heigh数组的有效范围是2~n for(int i = 0; i <= n; ++i) printf("%d ", heigh[i]);}int me;bool check(int x, int n) { int cnt = 1; for(int i = 2; i <= n; ++i) { if(heigh[i] >= x) { cnt++; }else { cnt = 1; } if(cnt >= me) return true; } return false;}int getp(int x, int n) { int cnt = 1, pos = -1, tmp = -1; for(int i = 2; i <= n; ++i) { if(heigh[i] >= x) { cnt++; tmp = max(tmp, max(sa[i - 1], sa[i])); }else { cnt = 1; tmp = -1; } if(cnt >= me) pos = max(pos, tmp); } if(cnt >= me) pos = max(pos, tmp); return pos;}void solve(int n) { int l = 1, r = n + 1; while(r - l > 1) { int mid = (l + r) >> 1; if(check(mid, n)) l = mid; else r = mid; } printf("%d %d\n", l, getp(l, n));}int main() { // freopen("in.txt", "r", stdin); // freopen("out1.txt", "w", stdout); while(scanf("%d", &me) == 1&& me) { scanf("%s", s); int n = strlen(s); da(s, sa, Rank, heigh, n, 130); // out(n); if(me == 1) printf("%d %d\n", n, 0); else if(check(1, n) == false) puts("none"); else solve(n); } return 0;}/*3vfskumskkjuoooqmuwunamayoclhpmexorddoimixgvxsukjlekpgmoganvmnfwqhgalvosjb*/
Suffixarray

后缀数组实现的时候还是对height数组的应用,同样是二分出一个L后,我们可以通过扫描一遍height数组来看满足的L长子串存不存在。若在heigh数组中,存在i属于[l,r],使得

heigh[i]  >= L且(r-l+1) >= m,  那么满足条件

转载于:https://www.cnblogs.com/orchidzjl/p/5081964.html

你可能感兴趣的文章
H&|~D&U &6&0&3&4
查看>>
springmvc的渲染
查看>>
OfType 使用LINQ查询动态数组中指定类型的元素
查看>>
linux环境中如何删除文件的前n行?
查看>>
.Net转Java自学之路—SpringMVC框架篇七(Json数据交互)
查看>>
jQuery通过name获取值
查看>>
团队任务二
查看>>
Python读写excel
查看>>
phpcms网站搬家 至 服务器 完整并且详细过程
查看>>
myBatis针对不同数据库的模糊查询
查看>>
列表转字典
查看>>
编译基于obs-studio的阿里巴巴直播工具tblive的过程和常见问题解决
查看>>
mac下使用gnu gcc
查看>>
html标签整合和css框架处理
查看>>
MySQL 分区表
查看>>
datasg中的数据的存储结
查看>>
SQL Server2008 程序设计 汇总 GROUP BY,WITH ROLLUP,WITH CUBE,GROUPING SETS(..)
查看>>
SQLAlchemy_ORM
查看>>
如何使用PHP操作cookie
查看>>
windows cmd命令学习
查看>>