[洛谷P2408]不同子串个数
题目大意:给你一个字符串,求其中本质不同的字串的个数
题解:同[洛谷P4070][SDOI2016]生成魔咒,只要最后再输出就行了
卡点:无
C++ Code:
#include <cstdio> #include <map> #define maxn 100010 long long ans; namespace SAM { #define N (maxn << 1) #define root 1 int R[N], fail[N]; int nxt[N][26]; int lst = root, idx = root; void append(char __ch) { int ch = __ch - 'a'; int p = lst, np = lst = ++idx; R[np] = R[p] + 1; for (; p && !nxt[p][ch]; p = fail[p]) nxt[p][ch] = np; if (!p) fail[np] = root; else { int q = nxt[p][ch]; if (R[p] + 1 == R[q]) fail[np] = q; else { int nq = ++idx; std::copy(nxt[q], nxt[q] + 26, nxt[nq]); fail[nq] = fail[q], R[nq] = R[p] + 1, fail[np] = fail[q] = nq; for (; p && nxt[p][ch] && nxt[p][ch] == q; p = fail[p]) nxt[p][ch] = nq; } } } int query() { return R[lst] - R[fail[lst]]; } #undef root #undef N } #define maxn 100010 int n; char s[maxn]; int main() { scanf("%d%s", &n, s); for (int i = 0; i < n; i++) { SAM::append(s[i]); ans += SAM::query(); } printf("%lld\n", ans); return 0; }