rt,题解和讨论区的 hack 均过了,拍也拍不出来,求大佬调。
#include <bits/stdc++.h>
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define ll long long
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
inline int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') f = c == '-' ? -1 : f, c = getchar();
while (c >= '0' && c <= '9') x = (x<<3)+(x<<1)+(c^48), c = getchar();
return x*f;
}
inline void write(int x) {
if (x < 0) x = -x, putchar('-');
if (x > 9) write(x/10);
putchar('0'+x%10);
}
const int N = 1e5+5, inf = 1e9;
struct seg {
int sum, res, lmx, rmx, col, len;
seg(int sum = 0, int res = 0, int lmx = 0, int rmx = 0, int col = 0, int len = 0):sum(sum), res(res), lmx(lmx), rmx(rmx), col(col), len(len) {}
} t[N<<2];
int n, m, idx, a[N], d[N], fa[N], id[N], to[N], siz[N], son[N], top[N];
vector <int> E[N];
void dfs1(int x, int f) {
d[x] = d[f]+1, fa[x] = f, siz[x] = 1; int mx = 0;
for (int y:E[x]) if (y != f) {
dfs1(y, x);
siz[x] += siz[y];
if (siz[y] > mx) son[x] = y, mx = siz[y];
}
}
void dfs2(int x, int topf) {
id[x] = ++idx, to[idx] = x, top[x] = topf;
if (!son[x]) return;
dfs2(son[x], topf);
for (int y:E[x]) if (y != fa[x] && y != son[x]) dfs2(y, y);
}
void pushup(int p) {
t[p].sum = t[ls].sum+t[rs].sum;
t[p].lmx = max(t[ls].lmx, t[ls].sum+t[rs].lmx);
t[p].rmx = max(t[rs].rmx, t[rs].sum+t[ls].rmx);
t[p].res = max(max(t[ls].res, t[rs].res), t[ls].rmx+t[rs].lmx);
}
void pushdown(int p) {
if (t[p].col == inf) return;
t[ls].sum = t[p].col*t[ls].len;
t[rs].sum = t[p].col*t[rs].len;
t[ls].res = t[ls].lmx = t[ls].rmx = max(0, t[ls].sum);
t[rs].res = t[rs].lmx = t[rs].rmx = max(0, t[rs].sum);
t[ls].col = t[rs].col = t[p].col;
t[p].col = inf;
}
void build(int p, int l, int r) {
t[p].col = inf, t[p].len = r-l+1;
if (l == r) {
t[p].sum = a[to[l]];
t[p].res = t[p].lmx = t[p].rmx = max(0, a[to[l]]);
return;
}
int mid = l+r>>1;
build(ls, l, mid), build(rs, mid+1, r);
pushup(p);
}
void upd(int p, int l, int r, int ql, int qr, int x) {
if (qr < l || r < ql) return;
if (ql <= l && r <= qr) {
t[p].sum = x*t[p].len;
t[p].res = t[p].lmx = t[p].rmx = max(0, t[p].sum);
t[p].col = x;
return;
}
pushdown(p); int mid = l+r>>1;
upd(ls, l, mid, ql, qr, x), upd(rs, mid+1, r, ql, qr, x);
pushup(p);
}
seg que(int p, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) return t[p];
pushdown(p); int mid = l+r>>1;
if (qr <= mid) return que(ls, l, mid, ql, qr);
if (mid < ql) return que(rs, mid+1, r, ql, qr);
seg x = que(ls, l, mid, ql, qr), y = que(rs, mid+1, r, ql, qr), res;
res.sum = x.sum+y.sum;
res.lmx = max(x.lmx, x.sum+y.lmx);
res.rmx = max(y.rmx, y.sum+x.rmx);
res.res = max(max(x.res, y.res), x.rmx+y.lmx);
return res;
}
void modify(int x, int y, int k) {
while (top[x] != top[y]) {
if (d[top[x]] < d[top[y]]) swap(x, y);
upd(1, 1, n, id[top[x]], id[x], k);
x = fa[top[x]];
}
if (d[x] > d[y]) swap(x, y);
upd(1, 1, n, id[x], id[y], k);
}
int solve(int x, int y) {
seg l, r;
while (top[x] != top[y]) {
if (d[top[x]] < d[top[y]]) swap(x, y), swap(l, r);
seg k = que(1, 1, n, id[top[x]], id[x]), res;
res.sum = l.sum+k.sum;
res.lmx = max(l.lmx, l.sum+k.rmx);
res.rmx = max(k.lmx, k.sum+l.rmx);
res.res = max(max(l.res, k.res), l.rmx+k.rmx);
l = res;
x = fa[top[x]];
}
if (d[x] > d[y]) swap(x, y), swap(l, r);
seg k = que(1, 1, n, id[x], id[y]), res;
res.sum = l.sum+k.sum;
res.lmx = max(l.lmx, l.sum+k.rmx);
res.rmx = max(k.lmx, k.sum+l.rmx);
res.res = max(max(l.res, k.res), l.rmx+k.rmx);
l = res;
return max(max(l.res, r.res), l.rmx+r.rmx);
}
void print(int p, int l, int r) {
printf("%d:[%d,%d]:\nsum:%dres:%dlmx:%drmx:%d\n", p, l, r, t[p].sum, t[p].res, t[p].lmx, t[p].rmx);
if (l == r) return;
int mid = l+r>>1;
print(ls, l, mid), print(rs, mid+1, r);
}
int main() {
n = read();
for (int i = 1; i <= n; ++i) a[i] = read();
for (int i = 1; i < n; ++i) {
int x = read(), y = read();
E[x].pb(y), E[y].pb(x);
}
dfs1(1, 0), dfs2(1, 1), build(1, 1, n);
//for (int i = 1; i <= n; ++i) printf("%d ", top[i]); enter;
//print(1, 1, n);
m = read();
while (m--) {
int op = read(), x = read(), y = read(), k;
if (op == 1) write(solve(x, y)), enter;
else k = read(), modify(x, y, k);
}
return 0;
}