http://www.lydsy.com/JudgeOnline/problem.php?id=3879
The Chinese of SVT is suffix virtual tree?
Anyway this konjac konjac do not understand, or $o (NLOGN) $ suffix array and the monotonic stack maintenance to do, Fye learned elder sister said this study method (at that time did not understand Qwq), Xiaoyimi taught me this practice →xiaoyimi the solution.
First contributed 2 times tle, thought it was the death circle of metaphysics, decisively hung up on the camera for a night, and then on the way home to think of Tle is because the time of submission forgot to delete freopen
#include <cstdio> #include <cstring> #include <algorithm>using namespace Std;typedef long ll; const int N = 500003;const ll p = 23333333333333333ll;int in () {int k = 0, fh = 1; char c = GetChar (); for (; c < ' 0 ' | | c > ' 9 '; c = GetChar ()) if (c = = '-') FH =-1; for (; c >= ' 0 ' && C <= ' 9 '; c = GetChar ()) K = (k << 3) + (k << 1) + C-' 0 '; return k * FH; int c[n], t1[n], t2[n]; void St (int *x, int *y, int *sa, int n, int m) {for (int i = 0; i < m; ++i) c[i] = 0; for (int i = 0; i < n; ++i) ++c[x[y[i]]; for (int i = 1; i < m; ++i) c[i] + = c[i-1]; for (int i = n-1; I >= 0; i) sa[--c[x[y[i]]] [= Y[i];} void mkhz (int *r, int *sa, int n, int m) {int *x = t1, *y = t2, *t, p, I, J; for (i = 0; i < n; ++i) x[i] = R[i], y[i] = i; St (x, y, SA, N, M); for (P = 1, j = 1; p < n; m = p, j <<= 1) {for (P = 0, i = n-j; i < n; ++i) y[p++] = i; for (i = 0; I &Lt N ++i) if (Sa[i] >= j) y[p++] = sa[i]-J; St (x, y, SA, N, M); for (t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; ++i) x[sa[i]] = y[sa[i] [= y[sa[i-1]] &&A mp Y[sa[i] + j] = = Y[sa[i-1] + j]? P-1: p++; }} void Mkh (int *r, int *sa, int *rank, int *h, int n) {int k = 0, J, I; for (i = 0; i < n; ++i) rank[sa[i]] = i; for (i = 1; l < n; h[rank[i++]] = k) for (K---k:0, j = sa[rank[i]-1]; R[i + K] = = R[j + K]; ++k);} Char S[n];int N, M, Sa[n], rank[n], r[n], h[n], f[n][20], log_2[n], a[n]; int get_min (int l, int r) {int len = log_2[r-l]; return min (F[l][len], F[r-(1 << len)][len]);} int GET_LCP (int l, int r) {L = Rank[l]; r = Rank[r]; if (L > R) Swap (L, R); Return Get_min (L, r);} BOOL CMP (int x, int y) {return rank[x] < rank[y];} int Sta[n], top, bef[n], size[n]; void Sub (ll &x, ll y) {x-= y; if (x < 0) x + = p;} void Add (ll &x, ll y) {x + = y;if (x > P) x-= p;} int main () {n = in (); m = in (); scanf ("%s", S + 1); R[0] = 0; for (int i = 1; I <= n; ++i) r[i] = s[i]-' a ' + 1; Mkhz (R, SA, n + 1, 27); Mkh (R, SA, rank, h, n + 1); for (int i = 0; i < n; ++i) f[i][0] = h[i + 1]; for (int j = 1, J < ++j) for (int i = 0; i < n; ++i) {if (i + (1 << (j-1)) >= N) Bre Ak F[i][j] = min (f[i][j-1], f[i + (1 << (j-1))][j-1]); } int tmp = 0; for (int i = 1; I <= n; ++i) {if ((1 << (tmp + 1)) < i) ++tmp; Log_2[i] = tmp; } int tot; ll sum, ans = 0; while (m--) {tot = in (); for (int i = 1; I <= tot; ++i) a[i] = in (); Sort (A + 1, a + tot + 1, CMP); tot = unique (A + 1, a + tot + 1)-A; --tot; for (int i = 1; i < tot; ++i) bef[i] = GET_LCP (A[i], a[i + 1]); top = 0; sum = 0; Ans = 0; for (int i = 1; i < tot; ++i) { Size[i] = 1; while (top && bef[i] < Bef[sta[top]) {sub (sum, 1LL * bef[sta[top] [size[sta[top]]% p); Size[i] + = Size[sta[top]]; --top; } Sta[++top] = i; Add (Sum, 1LL * bef[i] * size[i]% P); Add (ans, sum); } printf ("%lld\n", ans); } return 0;}
Once again, I was moved by my IQ Qaq
"Bzoj 3879" SvT