@@ -141,7 +141,7 @@ \subsection{后缀自动机}\label{ux540eux7f00ux81eaux52a8ux673a}}
141141 if(len[q] == len[p] + 1) fa[np] = q;
142142 else {
143143 int nq = ++tot;
144- for(int i = 0; i < 26; i++) ch[nq][i] = ch[q][i];
144+ for(int i = 0; i < 26; i++) ch[nq][i] = ch[q][i]; //for(int i = 0; i < 26; i++) ch[nq][i] = ch[q][i];
145145 fa[nq] = fa[q], fa[np] = fa[q] = nq, len[nq] = len[p] + 1;
146146 for(; ch[p][x] == q; p = fa[p]) ch[p][x] = nq;
147147 }
@@ -150,6 +150,34 @@ \subsection{后缀自动机}\label{ux540eux7f00ux81eaux52a8ux673a}}
150150}sam;
151151\end {minted }
152152
153+ \begin {itemize }
154+ \tightlist
155+ \item
156+ 最长公共子串
157+ \end {itemize }
158+
159+ \begin {minted }[fontsize=\footnotesize ,breaklines,linenos]{cpp}
160+ //*最长公共子串
161+ string lcs(const string &T) {
162+ int v = 0, l = 0, best = 0, bestpos = 0;
163+ for (int i = 0; i < T.size(); i++) {
164+ while (v && !sam.ch[v][T[i] - 'a' ]) {
165+ v = sam.fa[v];
166+ l = sam.len[v];
167+ }
168+ if (sam.ch[v][T[i] - 'a' ]) {
169+ v = sam.ch[v][T[i] - 'a' ];
170+ l++;
171+ }
172+ if (l > best) {
173+ best = l;
174+ bestpos = i;
175+ }
176+ }
177+ return T.substr(bestpos - best + 1, best);
178+ }
179+ \end {minted }
180+
153181\begin {itemize }
154182\tightlist
155183\item
@@ -388,6 +416,184 @@ \subsection{后缀自动机}\label{ux540eux7f00ux81eaux52a8ux673a}}
388416}
389417\end {minted }
390418
419+ \begin {itemize }
420+ \tightlist
421+ \item
422+ 维护区间本质不同字串数目
423+ \item
424+ 给你一个长度为\( n\) 的字符串\( s\) ,\( m\) 次询问,第\( i\) 次询问\( s\) 上的一个区间\( [l_i,r_i]\) 上有多少个本质不同的子串
425+ \end {itemize }
426+
427+ \begin {minted }[fontsize=\footnotesize ,breaklines,linenos]{cpp}
428+ #include<bits/stdc++.h>
429+ using namespace std;
430+ #define Re register int
431+ typedef long long ll;
432+
433+ const int N = 200005;
434+ struct info
435+ {
436+ int id, t;
437+ };
438+ int n, m, lst, num, res, g[N], ls[N], len[N], lk[N], ch[N][28], lt[N], son[N][2];
439+ char s[N];
440+ bool lz[N];
441+ ll sum[N << 2], ad[N << 2], ans[N];
442+ vector<info> q[N];
443+
444+ inline int read()
445+ {
446+ char c = getchar();
447+ int ans = 0;
448+ while (c < 48 || c > 57) c = getchar();
449+ while (c >= 48 && c <= 57) ans = (ans << 3) + (ans << 1) + (c ^ 48), c = getchar();
450+ return ans;
451+ }
452+
453+ inline void write(ll x)
454+ {
455+ int num = 0;
456+ char sc[25];
457+ if (!x) sc[num = 1] = 48;
458+ while (x) sc[++num] = x % 10 + 48, x /= 10;
459+ while (num) putchar(sc[num--]);
460+ putchar('\n ');
461+ }
462+
463+ inline void push_down(int id, int l, int mid, int r)
464+ {
465+ sum[id << 1] += ad[id] * (mid - l + 1), sum[id << 1 | 1] += ad[id] * (r - mid);
466+ ad[id << 1] += ad[id], ad[id << 1 | 1] += ad[id];
467+ ad[id] = 0;
468+ }
469+
470+ inline void modfy(int id, int l, int r, int x, int y, int z)
471+ {
472+ if (x <= l && r <= y)
473+ {
474+ sum[id] += 1ll * z * (r - l + 1), ad[id] += z;
475+ return;
476+ }
477+ int mid = l + r >> 1;
478+ if (ad[id]) push_down(id, l, mid, r);
479+ if (x <= mid) modfy(id << 1, l, mid, x, y, z);
480+ if (y > mid) modfy(id << 1 | 1, mid + 1, r, x, y, z);
481+ sum[id] = sum[id << 1] + sum[id << 1 | 1];
482+ }
483+
484+ inline ll que(int id, int l, int r, int x, int y)
485+ {
486+ if (x <= l && r <= y) return sum[id];
487+ int mid = l + r >> 1;
488+ ll ans = 0;
489+ if (ad[id]) push_down(id, l, mid, r);
490+ if (x <= mid) ans = que(id << 1, l, mid, x, y);
491+ if (y > mid) ans += que(id << 1 | 1, mid + 1, r, x, y);
492+ return ans;
493+ }
494+
495+ inline bool check(int x)
496+ {
497+ return son[lk[x]][0] == x || son[lk[x]][1] == x;
498+ }
499+
500+ inline void pushdown(int x)
501+ {
502+ if (son[x][0]) lt[son[x][0]] = lt[x], lz[son[x][0]] = 1;
503+ if (son[x][1]) lt[son[x][1]] = lt[x], lz[son[x][1]] = 1;
504+ lz[x] = 0;
505+ }
506+
507+ inline void rotate(int x)
508+ {
509+ int y = lk[x], z = lk[y];
510+ bool t = son[y][1] ^ x;
511+ if (check(y)) son[z][son[z][1] == y] = x;
512+ lk[x] = z, lk[y] = x;
513+ if (son[x][t]) lk[son[x][t]] = y;
514+ son[y][t ^ 1] = son[x][t], son[x][t] = y;
515+ }
516+
517+ inline void splay(int x)
518+ {
519+ g[res = 1] = x;
520+ while (check(g[res])) g[res + 1] = lk[g[res]], ++res;
521+ while (res)
522+ {
523+ if (lz[g[res]]) pushdown(g[res]);
524+ --res;
525+ }
526+ while (check(x))
527+ {
528+ int y = lk[x];
529+ if (check(y)) rotate(((son[y][1] == x) ^ (son[lk[y]][1] == y)) ? x : y);
530+ rotate(x);
531+ }
532+ }
533+
534+ inline int find(int x)
535+ {
536+ if (!x) return 0;
537+ splay(x);
538+ while (son[x][1]) x = son[x][1];
539+ return len[x];
540+ }
541+
542+ inline void access(int x, int y)
543+ {
544+ for (Re i = 0; x; x = lk[i = x])
545+ {
546+ splay(x);
547+ if (lz[x]) pushdown(x);
548+ if (lt[x]) modfy(1, 1, n, lt[x] - len[x] + 1, lt[x] - len[lk[x]], -1);
549+ son[x][1] = i;
550+ }
551+ splay(1), lt[1] = y, lz[1] = 1;
552+ }
553+
554+ inline void ins(int x)
555+ {
556+ int y = ++num;
557+ len[y] = len[lst] + 1;
558+ while (lst && !ch[lst][x]) ch[lst][x] = y, lst = lk[lst];
559+ if (lst)
560+ {
561+ int q = ch[lst][x];
562+ if (len[q] == len[lst] + 1) lk[y] = q;
563+ else
564+ {
565+ len[++num] = len[lst] + 1, lk[num] = lk[q], lk[q] = lk[y] = num;
566+ memcpy(ch[num], ch[q], sizeof ch[num]);
567+ while (lst && ch[lst][x] == q) ch[lst][x] = num, lst = lk[lst];
568+ }
569+ }
570+ else lk[y] = 1;
571+ lst = y;
572+ }
573+
574+ int main()
575+ {
576+ scanf("% s", s + 1);
577+ n = strlen(s + 1), m = read();
578+ for (Re i = 0; i < m; ++i)
579+ {
580+ int u = read(), v = read();
581+ q[v].push_back(info{i, u});
582+ }
583+ lst = num = 1;
584+ for (Re i = 1; i <= n; ++i) ins(s[i] - 97), ls[i] = lst;
585+ for (Re i = 1; i <= n; ++i)
586+ {
587+ access(ls[i], i), modfy(1, 1, n, 1, i, 1);
588+ int u = q[i].size();
589+ for (Re j = 0; j < u; ++j) ans[q[i][j].id] = que(1, 1, n, q[i][j].t, i);
590+ }
591+ for (Re i = 0; i < m; ++i) write(ans[i]);
592+ return 0;
593+ }
594+
595+ \end {minted }
596+
391597\hypertarget {ux56deux6587ux81eaux52a8ux673a}{%
392598\subsection {回文自动机 }\label {ux56deux6587ux81eaux52a8ux673a }}
393599
0 commit comments