#include<iostream> #include<stack> #include<cstring> #define maxn 500010 #define ll long long #define INF 1000000000 usingnamespacestd;
int n, k; char s[maxn];
int tax[maxn], tp[maxn], sa[maxn], rk[maxn], M = 255; voidrsort(){ for (int i = 0; i <= M; ++i) tax[i] = 0; for (int i = 1; i <= n; ++i) ++tax[rk[i]]; for (int i = 1; i <= M; ++i) tax[i] += tax[i - 1]; for (int i = n; i; --i) sa[tax[rk[tp[i]]]--] = tp[i]; }
int H[maxn]; voidinit_sa(){ if (n == 1) return sa[1] = rk[1] = 1, void(); int cnt = 1; for (int i = 1; i <= n; ++i) rk[i] = s[i], tp[i] = i; rsort(); for (int k = 1; k < n; k *= 2) { if (cnt == n) break; M = cnt; cnt = 0; for (int i = n - k + 1; i <= n; ++i) tp[++cnt] = i; for (int i = 1; i <= n; ++i) if (sa[i] > k) tp[++cnt] = sa[i] - k; rsort(); swap(rk, tp); rk[sa[1]] = cnt = 1; for (int i = 2; i <= n; ++i) { if (tp[sa[i - 1]] != tp[sa[i]] || tp[sa[i - 1] + k] != tp[sa[i] + k]) ++cnt; rk[sa[i]] = cnt; } } int lcp = 0; for (int i = 1; i <= n; ++i) { if (lcp) --lcp; int j = sa[rk[i] - 1]; while (s[j + lcp] == s[i + lcp]) ++lcp; H[rk[i]] = lcp; } }
int l[maxn], r[maxn]; intmain(){ ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> s + 1; n = strlen(s + 1); init_sa(); stack<int> S; S.push(0); H[0] = H[n + 1] = -1; for (int i = 1; i <= n + 1; ++i) { while (!S.empty() && H[i] < H[S.top()]) r[S.top()] = i, S.pop(); l[i] = S.top(); S.push(i); } ll ans = 1ll * n * (n - 1) * (n + 1) / 2; for (int i = 1; i <= n; ++i) ans -= 2ll * H[i] * (r[i] - i) * (i - l[i]); cout << ans << "\n"; return0; }