题意:训练之南P225
分析:二分寻找长度,用hash值来比较长度为L的字串是否相等。
#include <bits/stdc++.h> using namespace std; typedef unsigned long long ull; const int N = 4e4 + 5; const int x = 123; ull H[N], _hash[N], xp[N]; int rk[N]; char str[N]; int m; void get_hash(char *s, int len) { H[len] = 0; for (int i=len-1; i>=0; --i) { H[i] = H[i+1] * x + (s[i] - ‘a‘); } xp[0] = 1; for (int i=1; i<len; ++i) { xp[i] = xp[i-1] * x; } } bool cmp(const int &a, const int &b) { return (_hash[a] < _hash[b] || (_hash[a] == _hash[b] && a < b)); } int check(int L, int len) { int cnt = 0, pos = -1, c = 0; for (int i=0; i<len-L+1; ++i) { rk[i] = i; _hash[i] = H[i] - H[i+L] * xp[L]; } sort (rk, rk+len-L+1, cmp); for (int i=0; i<len-L+1; ++i) { if (i == 0 || _hash[rk[i]] != _hash[rk[i-1]]) c = 0; if (++c >= m) pos = max (pos, rk[i]); } return pos; } int main(void) { while (scanf ("%d", &m) == 1) { if (!m) break; scanf ("%s", &str); int len = strlen (str); get_hash (str, len); if (check (1, len) == -1) puts ("none"); else { int l = 1, r = len + 1; while (r - l > 1) { int mid = l + r >> 1; if (check (mid, len) >= 0) l = mid; else r = mid; } printf ("%d %d\n", l, check (l, len)); } } return 0; }
时间: 2024-10-11 12:51:22