1
+ /* *
2
+ * @file 2133.cpp
3
+ * @author Macesuted ([email protected] )
4
+ * @date 2022-07-04
5
+ *
6
+ * @copyright Copyright (c) 2022
7
+ *
8
+ */
9
+
10
+ #include < bits/stdc++.h>
11
+ using namespace std ;
12
+
13
+ #ifndef LOCAL
14
+ #define endl ' \n '
15
+ #endif
16
+
17
+ bool mem1;
18
+
19
+ #define maxn 300005
20
+
21
+ typedef pair<int64_t , int64_t > pll;
22
+
23
+ int a[maxn], rk[maxn], ork[maxn << 1 ], buc[maxn], id[maxn], val[maxn], sa[maxn], h[maxn], fa[maxn], siz[maxn];
24
+ pll ht[maxn];
25
+ multiset<int > maxVal[maxn], minVal[maxn];
26
+
27
+ int getfa (int p) { return fa[p] == p ? p : fa[p] = getfa (fa[p]); }
28
+
29
+ void solve (void ) {
30
+ int n;
31
+ string s;
32
+ cin >> n >> s;
33
+ int m = max (n, 256 );
34
+ for (int i = 1 ; i <= n; i++) buc[rk[i] = s[i - 1 ]]++;
35
+ for (int i = 1 ; i <= m; i++) buc[i] += buc[i - 1 ];
36
+ for (int i = n; i; i--) sa[buc[rk[i]]--] = i;
37
+ for (int l = 1 ; l == 1 || n != m; l <<= 1 ) {
38
+ for (int i = n - l + 1 ; i <= n; i++) id[i + l - n] = i;
39
+ for (int i = 1 , j = l; i <= n; i++)
40
+ if (sa[i] > l) id[++j] = sa[i] - l;
41
+ for (int i = 1 ; i <= m; i++) buc[i] = 0 ;
42
+ for (int i = 1 ; i <= n; i++) buc[val[i] = rk[id[i]]]++;
43
+ for (int i = 1 ; i <= m; i++) buc[i] += buc[i - 1 ];
44
+ for (int i = n; i; i--) sa[buc[val[i]]--] = id[i];
45
+ for (int i = 1 ; i <= n; i++) ork[i] = rk[i];
46
+ m = 0 ;
47
+ for (int i = 1 ; i <= n; i++) {
48
+ if (ork[sa[i]] != ork[sa[i - 1 ]] || ork[sa[i] + l] != ork[sa[i - 1 ] + l]) m++;
49
+ rk[sa[i]] = m;
50
+ }
51
+ }
52
+ s.push_back (' #' );
53
+ for (int i = 1 ; i <= n; i++) {
54
+ if (rk[i] == 1 ) continue ;
55
+ h[rk[i]] = max (h[rk[i - 1 ]] - 1 , 0 );
56
+ while (s[sa[rk[i] - 1 ] + h[rk[i]] - 1 ] == s[i + h[rk[i]] - 1 ]) h[rk[i]]++;
57
+ }
58
+ for (int i = 1 ; i <= n; i++) cin >> a[rk[i]];
59
+ for (int i = 1 ; i <= n; i++) fa[i] = i, siz[i] = 1 , maxVal[i].insert (a[i]), minVal[i].insert (a[i]);
60
+ for (int i = 2 ; i <= n; i++) ht[i] = {h[i], i};
61
+ sort (ht + 2 , ht + n + 1 , greater<pll>());
62
+ int64_t ans1 = 0 , ans2 = 0 ;
63
+ stack<pll> ans;
64
+ for (int i = n - 1 , j = 2 ; ~i; i--) {
65
+ while (j <= n && ht[j].first >= i) {
66
+ int x = ht[j++].second , f1 = getfa (x - 1 ), f2 = getfa (x);
67
+ if (!ans1)
68
+ ans2 = max ((int64_t )*maxVal[f1].rbegin () * *maxVal[f2].rbegin (),
69
+ (int64_t )*minVal[f1].begin () * *minVal[f2].begin ());
70
+ ans1 += 1LL * siz[f1] * siz[f2];
71
+ ans2 = max ({ans2, (int64_t )*maxVal[f1].rbegin () * *maxVal[f2].rbegin (),
72
+ (int64_t )*minVal[f1].begin () * *minVal[f2].begin ()});
73
+ for (auto i : maxVal[f2]) maxVal[f1].insert (i);
74
+ for (auto i : minVal[f2]) minVal[f1].insert (i);
75
+ maxVal[f2].clear (), minVal[f2].clear ();
76
+ while (maxVal[f1].size () > 2 ) maxVal[f1].erase (maxVal[f1].begin ());
77
+ while (minVal[f1].size () > 2 ) minVal[f1].erase (--minVal[f1].end ());
78
+ siz[f1] += siz[f2], fa[f2] = f1;
79
+ }
80
+ ans.emplace (ans1, ans2);
81
+ }
82
+ while (!ans.empty ()) cout << ans.top ().first << ' ' << ans.top ().second << endl, ans.pop ();
83
+ return ;
84
+ }
85
+
86
+ bool mem2;
87
+
88
+ int main () {
89
+ ios::sync_with_stdio (false ), cin.tie (nullptr );
90
+ #ifdef LOCAL
91
+ cerr << " Memory Cost: " << abs (&mem1 - &mem2) / 1024 . / 1024 . << " MB" << endl;
92
+ #endif
93
+
94
+ int _ = 1 ;
95
+ while (_--) solve ();
96
+
97
+ #ifdef LOCAL
98
+ cerr << " Time Cost: " << clock () * 1000 . / CLOCKS_PER_SEC << " MS" << endl;
99
+ #endif
100
+ return 0 ;
101
+ }
0 commit comments