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
| #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 << "DBG: " << #args << " -> "; err(args); } while (0) #else #define dbg(...) #endif void err() { cout << 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 = 2E6 + 100;
namespace tree { #define lson l, (l + r) / 2 #define rson (l + r) / 2 + 1, r struct P { int w, ls, rs; } tr[N * 23]; int sz = 1; int _new(int w, int ls, int rs) { tr[sz] = {w, ls, rs}; return sz++; } int ins(int oo, int p, int l, int r) { if (p > r || l > p) return oo; const P& o = tr[oo]; if (l == r) return _new(o.w + 1, 0, 0); return _new(o.w + 1, ins(o.ls, p, lson), ins(o.rs, p, rson)); } bool query(int pp, int qq, int ql, int qr, int l, int r) { if (ql > r || l > qr) return false; const P &p = tr[pp], &q = tr[qq]; if (ql <= l && r <= qr) return q.w - p.w > 0; return query(p.ls, q.ls, ql, qr, lson) || query(p.rs, q.rs, ql, qr, rson); } }
struct SAM { int t[N][26], len[N] = {-1}, fa[N], sz = 2, last = 1, one[N], pos[N]; void ins(int ch, int pp) { int p = last, np = last = sz++; one[np] = pp; pos[np] = pp; 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]); one[nq] = one[q]; fa[nq] = fa[q]; fa[np] = fa[q] = nq; for (; t[p][ch] == q; p = fa[p]) t[p][ch] = nq; } } void init() { memset(t, 0, (sz + 10) * sizeof t[0]); last = 1; sz = 2; } } S, T;
char s[N], t[N]; int ml[N], ls, lt; int rt[N], in[N], out[N], clk, ridx[N]; vector<int> G[N]; void dfs(int u) { in[u] = ++clk; ridx[clk] = u; for (int& v: G[u]) dfs(v); out[u] = clk; }
void get_ml(int L, int R) { int u = 1, l = 0; FOR (i, 0, lt) { int ch = t[i] - 'a', _; while (u && (!(_ = S.t[u][ch]) || !tree::query(rt[in[_] - 1], rt[out[_]], L + l, R, 0, N))) { if (--l == S.len[S.fa[u]]) u = S.fa[u]; // !!! } ++l; u = S.t[u][ch]; if (!u) u = 1; ml[i] = l; } }
int main() { freopen("name.in", "r", stdin); freopen("name.out", "w", stdout); memset(S.pos, -1, sizeof S.pos); scanf("%s", s); ls = strlen(s); FOR (i, 0, ls) S.ins(s[i] - 'a', i); FOR (i, 2, S.sz) G[S.fa[i]].push_back(i); dfs(1); FOR (i, 1, S.sz) { int pp = S.pos[ridx[i]]; rt[i] = pp == -1 ? rt[i - 1] : tree::ins(rt[i - 1], pp, 0, N); }
int Qn; cin >> Qn; while (Qn--) { T.init(); int l, r; scanf("%s%d%d", t, &l, &r); lt = strlen(t); FOR (i, 0, lt) T.ins(t[i] - 'a', i); get_ml(l - 1, r - 1); LL ans = 0; FOR (i, 2, T.sz) ans += max(0, T.len[i] - max(T.len[T.fa[i]], ml[T.one[i]])); cout << ans << endl; } }
|