首页 > 代码库 > UVA 11107 - Life Forms(Hash+LCP)
UVA 11107 - Life Forms(Hash+LCP)
UVA 11107 - Life Forms
题目链接
题意:给定一个字符串,找出重复出现超过m次的字串的最大开始下标
思路:hash大法,需要点人品,然后二分答案,每次利用hash值去找出最大下标即可
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef unsigned long long ull; const ull x = 123; const int N = 40005; int m, n; char str[N]; ull H[N], Hp[N]; void gethash() { H[n] = 0; for (int i = n - 1; i >= 0; i--) H[i] = H[i + 1] * x + str[i] - 'a'; } struct Suf { int hash, id; } suf[N]; bool cmp(Suf a, Suf b) { if (a.hash == b.hash) return a.id < b.id; return a.hash < b.hash; } int find(int L) { for (int i = 0; i < n - L + 1; i++) { suf[i].hash = H[i] - H[i + L] * Hp[L]; suf[i].id = i; } sort(suf, suf + n - L + 1, cmp); int ans = -1; for (int i = 0; i < n - L + 1; i++) { int j, len = 0; for (j = i; suf[i].hash == suf[j].hash && j < n - L + 1; j++) len++; if (len >= m) { ans = max(ans, suf[j - 1].id); } i = j - 1; } return ans; } void solve() { if (find(1) == -1) printf("none\n"); else { int l = 1, r = n - m + 2; while (l < r) { int mid = (l + r) / 2; if (find(mid) == -1) r = mid; else l = mid + 1; } printf("%d %d\n", l - 1, find(l - 1)); } } int main() { Hp[0] = 1; for (int i = 1; i < N; i++) Hp[i] = Hp[i - 1] * x; while (~scanf("%d", &m) && m) { scanf("%s", str); n = strlen(str); gethash(); solve(); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。