标签:信息 define push signed wap ring cstring def ace
并查集合并的时候更新信息。注意a[ i ] 有负的。
#include
#include
#include
#include
#include#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair#define PLI pair#define PII pair#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0);
using namespace std;
const int N = 3e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-8;
//const double PI = acos(-1);
templateclass T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;}
templateclass T, class S> inline void sub(T &a, S b) {a -= b; if(a 0) a += mod;}
templateclass T, class S> inline bool chkmax(T &a, S b) {return a true : false;}
templateclass T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;}
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int r[N], sa[N], _t[N], _t2[N], c[N], rk[N], lcp[N], san;
int maxc = 256;
void buildSa(int *r, int n, int m) {
int i, j = 0, k = 0, *x = _t, *y = _t2;
for(i = 0; i 0;
for(i = 0; i ;
for(i = 1; i 1];
for(i = n - 1; i >= 0; i--) sa[--c[x[i]]] = i;
for(int k = 1; k 1) {
int p = 0;
for(i = n - k; i i;
for(i = 0; i if(sa[i] >= k) y[p++] = sa[i] - k;
for(i = 0; i 0;
for(i = 0; i ;
for(i = 1; i 1];
for(i = n - 1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
swap(x, y);
p = 1; x[sa[0]] = 0;
for(int i = 1; i ) {
if(y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k])
x[sa[i]] = p - 1;
else x[sa[i]] = p++;
}
if(p >= n) break;
m = p;
}
for(i = 1; i i;
for(i = 0; i 1; i++) {
if(k) k--;
j = sa[rk[i] - 1];
while(r[i + k] == r[j + k]) k++;
lcp[rk[i]] = k;
}
}
int fa[N], dl[N], dr[N], sz[N], maxVal[N], minVal[N];
int n, maxH, a[N];
PLL ans[N];
char s[N];
vectorint> V[N];
int getRoot(int x) {
return x == fa[x] ? x : fa[x] = getRoot(fa[x]);
}
int Merge(int u, int v, LL &way, LL &mx) {
int x = getRoot(u);
int y = getRoot(v);
chkmax(mx, 1LL * maxVal[x] * maxVal[y]);
chkmax(mx, 1LL * minVal[x] * minVal[y]);
way += 1LL * sz[x] * sz[y];
fa[y] = x;
chkmin(dl[x], dl[y]);
chkmax(dr[x], dr[y]);
sz[x] += sz[y];
chkmax(maxVal[x], maxVal[y]);
chkmin(minVal[x], minVal[y]);
return x;
}
void printSuf(int x) {
for(int i = sa[x]; i char)r[i]);
for(int i = 0; i 5); i++) putchar(‘ ‘);
printf("sa: %d lcp: %d\n", sa[x], lcp[x]);
}
int main() {
scanf("%d", &n);
scanf("%s", s);
int maxPre = 0;
int minPre = 0;
for(int i = 0; i ) {
scanf("%d", &a[i]);
chkmax(ans[0].se, 1LL * maxPre * a[i]);
chkmax(ans[0].se, 1LL * minPre * a[i]);
chkmax(maxPre, a[i]);
chkmin(minPre, a[i]);
}
ans[0].fi = 1LL * n * (n - 1) / 2;
for(int i = 0; i ) {
r[san++] = s[i];
}
r[san] = 0;
buildSa(r, san + 1, maxc);
for(int i = 1; i ) {
V[lcp[i]].push_back(i);
chkmax(maxH, lcp[i]);
}
for(int i = 1; i ) {
fa[i] = dl[i] = dr[i] = i;
sz[i] = 1;
maxVal[i] = a[sa[i]];
minVal[i] = a[sa[i]];
}
LL way = 0, mx = -INF;
for(int i = maxH; i > 0; i--) {
for(int j = 0; j ) {
int t = V[i][j];
Merge(t - 1, t, way, mx);
}
ans[i].fi = way;
ans[i].se = mx;
}
for(int i = 0; i ) {
printf("%lld %lld\n", ans[i].fi, ans[i].se);
}
return 0;
}
/*
*/
bzoj 4119 后缀数组 + 并查集
标签:信息 define push signed wap ring cstring def ace
原文地址:https://www.cnblogs.com/CJLHY/p/11134616.html