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
| struct Segment_Tree { struct Node { int lc, rc, cnt; } tr[N << 6]; int cnt; void insert(int &rt, int l, int r, int pos) { if (!rt) rt = ++ cnt; if (l == r) return void(tr[rt].cnt = 1); int mid = (l + r) >> 1; if (pos <= mid) insert(tr[rt].lc, l, mid, pos); else insert(tr[rt].rc, mid + 1, r, pos); tr[rt].cnt = tr[tr[rt].lc].cnt + tr[tr[rt].rc].cnt; } int merge(int p, int q, int l = 1, int r = n) { if (!p || !q) return p | q; int cur = ++ cnt, mid = (l + r) >> 1; if (l == r) return tr[cur].cnt = tr[p].cnt | tr[q].cnt, cur; tr[cur].lc = merge(tr[p].lc, tr[q].lc, l, mid); tr[cur].rc = merge(tr[p].rc, tr[q].rc, mid + 1, r); tr[cur].cnt = tr[tr[cur].lc].cnt + tr[tr[cur].rc].cnt; return cur; } } seg;
struct SAM { struct Node { int ch[26], len, fa; } tr[N << 1]; int rt[N << 1], sz[N << 1]; int tot; std::vector<int> g[N << 1]; SAM() : tot(1) {} int extend(int ls, int c, int col) { if (tr[ls].ch[c]) { int p = ls, q = tr[p].ch[c]; if (tr[q].len == tr[p].len + 1) return seg.insert(rt[q], 1, n, col), q; int nq = ++ tot; seg.insert(rt[nq], 1, n, col); tr[nq] = tr[q], tr[nq].len = tr[p].len + 1; for (; p && tr[p].ch[c] == q; p = tr[p].fa) tr[p].ch[c] = nq; return tr[q].fa = nq, nq; } int p = ls, np = ++ tot; tr[np].len = tr[p].len + 1; seg.insert(rt[np], 1, n, col); for (; p && !tr[p].ch[c]; p = tr[p].fa) tr[p].ch[c] = np; if (!p) tr[np].fa = 1; else { int q = tr[p].ch[c]; if (tr[q].len == tr[p].len + 1) seg.insert(rt[q], 1, n, col), tr[np].fa = q; else { int nq = ++ tot; seg.insert(rt[nq], 1, n, col); tr[nq] = tr[q], tr[nq].len = tr[p].len + 1; for (; p && tr[p].ch[c] == q; p = tr[p].fa) tr[p].ch[c] = nq; tr[np].fa = tr[q].fa = nq; } } return np; } void dfs(int x) { for (int v : g[x]) dfs(v), rt[x] = seg.merge(rt[x], rt[v]); sz[x] = seg.tr[rt[x]].cnt; } void work() { for (int i = 2; i <= tot; ++ i) g[tr[i].fa].push_back(i); dfs(1); } } sam;
int main() { std::cin.tie(0)->sync_with_stdio(false); std::cin >> n >> k; for (int i = 1, ls; i <= n; ++ i) { std::cin >> s[i]; ls = 1; for (char c : s[i]) ls = sam.extend(ls, c - 'a', i); } sam.work(); for (int i = 1; i <= n; ++ i) { int p = 1; long long res = 0; for (char c : s[i]) { p = sam.tr[p].ch[c - 'a']; while (p != 1 && sam.sz[p] < k) p = sam.tr[p].fa; if (sam.sz[p] >= k) res += sam.tr[p].len; } std::cout << res << ' '; } return 0; }
|