After the suffix array is calculated, the height is sorted, from large to small (R similarity must be 0~r-1 similar), and the maintenance is checked. Complexity O (Nlogn + nalpha (N))
-----------------------------------------------------------------------------------
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long Long ll; Const LL INF = -1ll <<;const int MAXN = 300009;Char S[MAXN];int W[MAXN], N;int CNT[MAXN], SA[MAXN], RANK[MAXN], HEIGHT[MAXN];int MX[MAXN], MN[MAXN], FA[MAXN], SZ[MAXN], R[MAXN];ll ANS[MAXN], TOT[MAXN];void Init () {scanf ("%d%s", &n, s);for (int i = 0; i < N; i++) scanf ("%d", w + i);s[n++] = ' $ ';}void Build () {int m = 255, *x = Height, *y = Rank;for (int i = 0; i < m; i++) cnt[i] = 0;for (int i = 0; i < N; i++) cnt[x[i] = s[i]]++;for (int i = 1; i < m; i++) cnt[i] + = cnt[i-1];for (int i = N; i--;) Sa[--cnt[x[i]] = i;for (int k = 1, p = 0; k <= N; k <<= 1, p = 0) {for (int i = n-k; i < N; i++) y[p++] = i;for (int i = 0; i < N; i++)if (Sa[i] >= k) y[p++] = sa[i]-K;for (int i = 0; i < m; i++) cnt[i] = 0;for (int i = 0; i < N; i++) cnt[x[y[i]]]++;for (int i = 1; i < m; i++) cnt[i] + = cnt[i-1];for (int i = N; i--;) Sa[--cnt[x[y[i]] [y[i];swap (x, y), x[sa[0]] = 0, p = 1;for (int i = 1; i < N; i++) {if (y[sa[i]! = y[sa[i-1]] | | y[sa[i] + K]! = Y[sa[i-1] + K]) p++;X[sa[i]] = p-1;}if ((M = p) >= N) break;}for (int i = 0; i < N; i++) rank[sa[i]] = i;height[0] = 0;for (int i = 0, h = 0; i < N; i++) if (Rank[i]) {if (h) h--;while (s[i + h] = = S[sa[rank[i]-1] + h]) h++;Height[rank[i]] = h;}}int Find (int x) {return x = = Fa[x]? x:fa[x] = Find (fa[x]);} bool CMP (const int &L, const int &r) {return height[l] > Height[r];}inline void Max (ll &x, ll t) {if (T > x) x = t;}inline void Max (int &x, int t) {if (T > x) x = t;}inline void Min (int &x, int t) {if (t < x) x = t;}void Work () {for (int i = 0; i < N; i++) {Sz[i] = 1;R[i] = fa[i] = i;Mx[i] = mn[i] = W[i];Tot[i] = 0;ans[i] = INF;}sort (R, R + N, CMP);for (int i = 0; i < N; i++) if (R[i] > 1) {int u = FIND (Sa[r[i]]), V = Find (Sa[r[i]-1]);if (U = = v) continue;Tot[height[r[i]] + = LL (Sz[u]) * SZ[V];Max (Ans[height[r[i]], Max (LL (Mx[u]) * Mx[v], LL (Mn[u]) * mn[v]));Fa[u] = V, sz[v] + = Sz[u];Max (Mx[v], mx[u]);Min (Mn[v], mn[u]);}for (int i = height[r[0]]; i--;)Tot[i] + = tot[i + 1], Max (Ans[i], ans[i + 1]);for (int i = 0; i + 1 < N; i++)printf ("%lld%lld\n", Tot[i], ans[i]! = INF? Ans[i]: 0);}int main () {Init ();Build ();Work ();return 0;}
-----------------------------------------------------------------------------------
Bzoj 4199: [Noi2015] Wine tasting session (suffix array + and check set)