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
| #include <bits/stdc++.h> using namespace std; using LL = long long; #define FOR(i, x, y) for (decay<decltype(y)>::type i = (x), _##i = (y); i < _##i; ++i) #define FORD(i, x, y) for (decay<decltype(x)>::type i = (x), _##i = (y); i > _##i; --i) #ifdef zerol #define dbg(args...) do { cout << "\033[32;1m" << #args << " -> "; err(args); } while (0) #else #define dbg(...) #endif void err() { cout << "\033[39;0m" << endl; } template<template<typename...> class T, typename t, typename... Args> void err(T<t> a, Args... args) { for (auto x: a) cout << x << ' '; err(args...); } template<typename T, typename... Args> void err(T a, Args... args) { cout << a << ' '; err(args...); } // ----------------------------------------------------------------------------- const int N = 1E5 + 100;
namespace tree { #define mid ((l + r) >> 1) #define lson l, mid #define rson mid + 1, r struct P { int w, ls, rs; } tr[N * 20 * 18]; int sz = 1; int _new(int w, int ls, int rs) { tr[sz] = {w, ls, rs}; return sz++; } int ins(int tt, int x, int v, int l = -1, int r = N) { if (x < l || r < x) return tt; const P& t = tr[tt]; if (l == r) return _new(t.w + v, 0, 0); return _new(t.w + v, ins(t.ls, x, v, lson), ins(t.rs, x, v, rson)); } int query(int tt, int k, int l = -1, int r = N) { if (l == r) return l; const P& t = tr[tt]; int w = tr[t.rs].w; if (k <= w) return query(t.rs, k, rson); else return query(t.ls, k - w, lson); } };
namespace sam { const int M = N << 1; int t[M][26], len[M] = {-1}, fa[M], sz = 2, last = 1, ed[M]; void ins(int ch, int pp) { int p = last, np = last = sz++; ed[np] = pp + 1; len[np] = len[p] + 1; for (; p && !t[p][ch]; p = fa[p]) t[p][ch] = np; if (!p) { fa[np] = 1; return; } int q = t[p][ch]; if (len[p] + 1 == len[q]) fa[np] = q; else { int nq = sz++; len[nq] = len[p] + 1; memcpy(t[nq], t[q], sizeof t[0]); fa[nq] = fa[q]; fa[np] = fa[q] = nq; for (; t[p][ch] == q; p = fa[p]) t[p][ch] = nq; } }
int c[M] = {1}, a[M]; void rsort() { FOR (i, 1, sz) c[i] = 0; FOR (i, 1, sz) c[len[i]]++; FOR (i, 1, sz) c[i] += c[i - 1]; FOR (i, 1, sz) a[--c[len[i]]] = i; } } using namespace sam; set<int> e[M]; int d[M];
void s_ins(set<int>& e, int& d, int x) { auto it = e.insert(x).first, l = it, r = it; if (e.size() == 1) return; if (l != e.begin() && r != --e.end()) { int ll = *--l, rr = *++r; d = tree::ins(d, rr - ll, -1); d = tree::ins(d, x - ll, 1); d = tree::ins(d, rr - x, 1); } else { if (it != e.begin()) d = tree::ins(d, x - *--l, 1); else d = tree::ins(d, *++r - x, 1); } }
char s[N]; int main() { scanf("%s", s); int K; cin >> K; --K; FOR (i, 0, strlen(s)) ins(s[i] - 'a', i); rsort(); LL ans = 0;
FORD (i, sz - 1, 1) { int u = a[i], f = fa[u]; if (ed[u]) s_ins(e[u], d[u], ed[u]); int l, r; r = tree::query(d[u], K); l = tree::query(d[u], K + 1); ans += max(min(r - 1, len[u]) - max(l, len[fa[u]] + 1) + 1, 0); if (e[f].size() < e[u].size()) { swap(e[f], e[u]); swap(d[f], d[u]); } for (auto& x: e[u]) s_ins(e[f], d[f], x);
} cout << ans << endl; }
|