| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 
 | #include <cstdio>#include <algorithm>
 using namespace std;
 template <class Type>
 void read(Type &x)
 {
 char c;
 bool flag = false;
 while ((c = getchar()) < '0' || c > '9')
 c == '-' && (flag = true);
 x = c - '0';
 while ((c = getchar()) >= '0' && c <= '9')
 x = (x << 3) + (x << 1) + c - '0';
 if (flag) x = ~x + 1;
 }
 template <class Type, class ...rest>
 void read(Type &x, rest &...y) { read(x), read(y...); }
 template <class Type>
 void write(Type x)
 {
 if (x < 0) putchar('-'), x = ~x + 1;
 if (x > 9) write(x / 10);
 putchar(x % 10 + '0');
 }
 template <class Type>
 void chkmax (Type &x, Type k) { if (k > x) x = k; }
 template <class Type>
 void chkmin (Type &x, Type k) { if (k < x) x = k; }
 typedef long long LL;
 const LL Inf = 1e18;
 const int N = 6e5 + 10, inf = 1e9;
 struct Node { int s[2], l, r, mx, mn; } tr[N];
 char str[N];
 int top, stk[N];
 LL s[N], mx[N];
 int n, w[N], m, sa[N], rnk[N], ht[N], x[N], y[N], c[N];
 void bucsort ()
 {
 for (int i = 1; i <= m; ++i) c[i] = 0;
 for (int i = 1; i <= n; ++i) ++c[x[i]];
 for (int i = 2; i <= m; ++i) c[i] += c[i - 1];
 for (int i = n; i; i--) sa[c[x[y[i]]]--] = y[i];
 }
 void init ()
 {
 for (int i = 1; i <= n; ++i)
 x[i] = str[i] - 'a' + 1, y[i] = i, sa[i] = 0;
 bucsort();
 for (int k = 1; k <= n; k <<= 1)
 {
 int cnt = 0;
 for (int i = n - k + 1; i <= n; ++i) y[++cnt] = i;
 for (int i = 1; i <= n; ++i)
 if (sa[i] > k) y[++cnt] = sa[i] - k;
 bucsort();
 for (int i = 1; i <= n; ++i) y[i] = x[i];
 x[sa[1]] = cnt = 1;
 for (int i = 2; i <= n; ++i)
 x[sa[i]] = cnt += (y[sa[i]] ^ y[sa[i - 1]] || y[sa[i] + k] ^ y[sa[i - 1] + k]);
 if ((m = cnt) == n) break;
 }
 for (int i = 1; i <= n; ++i) rnk[sa[i]] = i;
 for (int i = 1, k = 0; i <= n; ++i)
 {
 int j = sa[rnk[i] - 1];
 if (k) --k;
 while (str[i + k] == str[j + k]) ++k;
 ht[rnk[i]] = k;
 }
 }
 void calc (int x)
 {
 tr[x].l = tr[x].r = x;
 tr[x].mx = -inf, tr[x].mn = inf;
 if (tr[x].s[0])
 calc(tr[x].s[0]), tr[x].l = tr[tr[x].s[0]].l;
 if (tr[x].s[1])
 calc(tr[x].s[1]), tr[x].r = tr[tr[x].s[1]].r;
 chkmax(tr[x].mx, tr[tr[x].s[0]].mx), chkmin(tr[x].mn, tr[tr[x].s[0]].mn);
 chkmax(tr[x].mx, tr[tr[x].s[1]].mx), chkmin(tr[x].mn, tr[tr[x].s[1]].mn);
 s[ht[x]] += (LL)(tr[x].r - x + 1) * (x - tr[x].l + 1);
 chkmax(mx[ht[x]], (LL)max(tr[tr[x].s[0]].mx, w[sa[tr[x].l - 1]]) * max(w[sa[x]], tr[tr[x].s[1]].mx));
 chkmax(mx[ht[x]], (LL)min(tr[tr[x].s[0]].mn, w[sa[tr[x].l - 1]]) * min(w[sa[x]], tr[tr[x].s[1]].mn));
 chkmax(tr[x].mx, w[sa[x]]), chkmin(tr[x].mn, w[sa[x]]);
 }
 int main ()
 {
 m = 26, read(n);
 if (n == 1) return puts("0 0"), 0;
 scanf("%s", str + 1);
 init();
 for (int i = 1; i <= n; ++i) read(w[i]);
 for (int i = 2; i <= n; ++i)
 {
 int t = top;
 while (t && ht[stk[t]] >= ht[i]) --t;
 if (t) tr[stk[t]].s[1] = i;
 if (t < top) tr[i].s[0] = stk[t + 1];
 stk[top = ++t] = i;
 }
 for (int i = 0; i < n; ++i) mx[i] = -Inf;
 tr[0].mn = inf, tr[0].mx = -inf;
 calc(stk[1]);
 for (int i = n - 2; ~i; --i)
 s[i] += s[i + 1], chkmax(mx[i], mx[i + 1]);
 for (int i = 0; i < n; ++i)
 write(s[i]), putchar(' '), write(s[i] ? mx[i] : 0), puts("");
 return 0;
 }
 
 |