1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
| #include <bits/stdc++.h> using namespace std;
const int SIGMA = 27; const int MAXN = 2e5 + 5;
int n, k; int f[MAXN << 1], s[MAXN << 1];
struct SAM { struct Node { int len, link; int trans[SIGMA]; } node[MAXN << 1]; #define len(u) node[u].len #define link(u) node[u].link #define trans(u, c) node[u].trans[c] int cnt, last; void init() { len(0) = 0; link(0) = -1; cnt = 0; last = 0; for (int i = 0; i < SIGMA; ++i) trans(0, i) = 0; } void insert(int c) { int cur = ++cnt; for (int i = 0; i < SIGMA; ++i) trans(cur, i) = 0; len(cur) = len(last) + 1; int p = last; while (p != -1 && trans(p, c) == 0) { trans(p, c) = cur; p = link(p); } if (p == -1) { link(cur) = 0; } else { int q = trans(p, c); if (len(p) + 1 == len(q)) { link(cur) = q; } else { int clone = ++cnt; for (int i = 0; i < SIGMA; ++i) trans(clone, i) = 0; len(clone) = len(p) + 1; for (int i = 0; i < SIGMA; ++i) trans(clone, i) = trans(q, i); link(clone) = link(q); while (p != -1 && trans(p, c) == q) { trans(p, c) = clone; p = link(p); } link(q) = link(cur) = clone; } } f[cur] = 1; last = cur; } } T;
struct Edge { int v, nxt; } edge[MAXN << 1]; int head[MAXN << 1], cnt; void AddEdge(int u, int v) { edge[++cnt].v = v; edge[cnt].nxt = head[u]; head[u] = cnt; }
void dfs(int u) { for (int i = head[u]; i; i = edge[i].nxt) { int v = edge[i].v; dfs(v); f[u] += f[v]; } if (u == 0) return; if (f[u] == k) { int l = T.node[T.node[u].link].len + 1; int r = T.node[u].len; s[l] += 1; s[r + 1] -= 1; } }
int t; char str[MAXN];
int main() { scanf("%d", &t); while (t--) { T.init(); scanf("%s", str + 1); n = strlen(str + 1); scanf("%d", &k); for (int i = 1; i <= n; ++i) T.insert(str[i] - 'a'); for (int i = 1; i <= T.cnt; ++i) { AddEdge(T.node[i].link, i); } dfs(0); int ans = -1, ans_val = 0; for (int i = 1; i <= n; ++i) { s[i] += s[i - 1]; if (s[i] && s[i] >= ans_val) ans = i, ans_val = s[i]; } printf("%d\n", ans); for (int i = 0; i <= T.cnt; ++i) { f[i] = 0; head[i] = 0; s[i] = 0; } cnt = 0; } return 0; }
|