boolcmp(int x, int y, int w){return trk[x] == trk[y] && trk[x + w] == trk[y + w];}
voidSA(int n){ staticint cnt[Maxn], id[Maxn]; int m = 300, p; // for (int i = 1; i <= n; ++i) ++cnt[rk[i] = s[i]]; // for (int i = 1; i <= m; ++i) cnt[i] += cnt[i - 1]; for (int i = n; i; --i) sa[cnt[rk[i]]--] = i; for (int w = 1; p != n; w <<= 1, m = p) { p = 0; for (int i = n; i > n - w; --i) id[++p] = i; for (int i = 1; i <= n; ++i) if (sa[i] > w) id[++p] = sa[i] - w; memset(cnt, 0, sizeof(cnt)); for (int i = 1; i <= n; ++i) ++cnt[rk[id[i]]]; // for (int i = 1; i <= m; ++i) cnt[i] += cnt[i - 1]; for (int i = n; i; --i) sa[cnt[rk[id[i]]]--] = id[i]; memcpy(trk, rk, sizeof(trk)); p = 0; // for (int i = 1; i <= n; ++i) rk[sa[i]] = cmp(sa[i], sa[i - 1], w) ? p : ++p; if (p == n) for (int i = 1; i <= n; ++i) sa[rk[i]] = i; } for (int i = 1, k = 0; i <= n; ++i) { if (k) --k; while (s[i + k] == s[sa[rk[i] - 1] + k]) ++k; // h[rk[i]] = k; } }
int stc[Maxn], top, l[Maxn], r[Maxn];
signedmain(){ scanf("%s", s + 1); int n = strlen(s + 1); SA(n); stc[top = 1] = 1; for (int i = 2; i <= n; ++i) { while (top && h[stc[top]] > h[i]) r[stc[top--]] = i; l[i] = stc[top], stc[++top] = i; } while (top) r[stc[top--]] = n + 1; longlong ans = 1ll * (n - 1) * n * (n + 1) / 2; for (int i = 2; i <= n; ++i) ans -= 2ll * (r[i] - i) * (i - l[i]) * h[i]; print(ans); return0; }
// Code By CloudySky #include<bits/stdc++.h> // #define int long long namespace IO { inlineintread(){ int x = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();} while (c >= '0' && c <= '9') x = x * 10 + (c ^ 48), c = getchar(); return x * f; } voidprint_n(int x){ if (x > 9) print_n(x / 10); putchar(x % 10 + '0'); } inlinevoidprint(int x, char s = '\n'){ if (x < 0) putchar('-'), x = -x; print_n(x), putchar(s); } } // namespace IO usingnamespace IO; voidopenfile(); constint Maxn = 1e6 + 10; usingnamespace std;
int sam[Maxn][26], siz[Maxn], fail[Maxn], len[Maxn], lst, tot;
voidinsert(char c){ int p = lst, np = ++tot, ch = c - 'a'; lst = np, len[np] = len[p] + 1, siz[np] = 1; for (; p != -1 && !sam[p][ch]; p = fail[p]) sam[p][ch] = np; if (p == -1) return fail[np] = 0, void(); int q = sam[p][ch]; if (len[q] == len[p] + 1) return fail[np] = q, void(); int nq = ++tot; fail[nq] = fail[q], fail[q] = fail[np] = nq; memcpy(sam[nq], sam[q], sizeof(sam[nq])); len[nq] = len[p] + 1; for (; p != -1 && sam[p][ch] == q; p = fail[p]) sam[p][ch] = nq; }
char s[Maxn];
voidSAM(){ fail[0] = -1, lst = tot = 0; int n = strlen(s); for (int i = n - 1; i >= 0; --i) insert(s[i]); }
longlong ans; vector <int> g[Maxn];
voiddfs(int x){ int st = siz[x]; for (int y : g[x]) dfs(y), siz[x] += siz[y]; for (int y : g[x]) ans += 1ll * siz[y] * (siz[x] - siz[y]) * len[x]; ans += 1ll * st * (siz[x] - st) * len[x]; }
signedmain(){ openfile(); scanf("%s", s), SAM(); int n = strlen(s); for (int i = 1; i <= tot; ++i) g[fail[i]].push_back(i); dfs(0); printf("%lld\n", 1ll * (n - 1) * n * (n + 1) / 2 - ans); return0; }