http://cplusoj.com/d/senior/p/SS20240103A
显然可以点分树,然后被卡空间
任何一条树上的链都可以这样表示:
因此我们可以把所有轻儿子挂在重链上,然后求重链的最大子段和
因为我们要支持删除,同时树上每个节点要求连出去轻儿子中的最大,因此我们树上每个节点拿个set维护所有轻儿子
pre coding at 14:46
st coding at 15:09
st bugging at 17:08
passing at 20:27
fn blogging at 20:39
// 7.2k
#include<bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#define debug(...) fprintf(stderr, ##__VA_ARGS__)
#else
#define debug(...) void(0)
#endif
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
#define Z(x) (x)*(x)
#define pb push_back
#define fi first
#define se second
//#define M
//#define mo
#define N 1000010
int n, m, i, j, k, T;
multiset<int>ans_set;
int dep[N], a[N], F[N], w[N], top[N], Ed[N], son[N], tot, u, v;
int dfn[N], q, op, dfn_xu[N];
vector<int>G[N];
struct Segment_tree {
#define ls (k<<1)
#define rs (k<<1|1)
#define mid ((l+r)>>1)
struct node {
int s, L, R, mx;
void mem() { s = L = R = mx = 0; }
node operator + (const node &a) const {
node b; b.mem();
b.s = s + a.s;
b.L = max(L, s + a.L);
b.R = max(a.R, R + a.s);
b.mx = max({mx, a.mx, R + a.L});
return b;
}
}a[N<<2];
multiset<int>s[N<<2];
void push_up(int k) {
a[k] = a[ls] + a[rs];
}
void build(int k, int l, int r, int *A) {
if(l == r) {
a[k].s = a[k].mx = a[k].L = a[k].R = A[dfn_xu[l]]; s[k].insert(0);
// debug("[%lld] : %lld | %lld\n", l, a[k].mx, A[dfn_xu[l]]);
return ;
}
build(ls, l, mid, A); build(rs, mid+1, r, A);
push_up(k);
}
void add(int k, int l, int r, int x, int y) {
assert(x >= 1 && x <= n);
if(l == r) {
a[k].s = y; auto t = s[k].end(); --t;
a[k].L = a[k].R = a[k].mx = y + (*t);
if(s[k].size() >= 2) { --t; a[k].mx += max(0ll, (*t)); }
// debug("So a[k[%lld]].s = %lld | mx = %lld\n", l, a[k].s, a[k].mx);
return ;
}
if(x <= mid) add(ls, l, mid, x, y);
else add(rs, mid + 1, r, x, y);
push_up(k);
}
void update(int k, int l, int r, int x, int y, int o) {
assert(x >= 1 && x <= n);
assert(k > 0 && k <= 4*n);
assert(l <= r && l >= 1 && r <= n);
assert(y <= 1e18);
// if(q == 80769) debug("[%lld] [%lld %lld] %lld => %lld | %lld\n", k, l, r, x, y, o);
if(l == r) {
if(k == 215325) debug("%lld [%lld] || %d\n", y, o, s[k].size());
if(o == 1) s[k].insert(y);
else {
if(s[k].find(y) == s[k].end()) debug("fdsfdasfadfasd\n");
s[k].erase(s[k].find(y));
}
if(k == 215325) debug("%lld [%lld] || %d\n", y, o, s[k].size());
assert(!s[k].empty());
auto t = s[k].end(); --t;
a[k].L = a[k].R = a[k].mx = a[k].s + (*t);
// debuug("upd")
// debug(" %lld : %lld | %lld\n", x, a[k].mx, (*t));
// debug("%lld : %lld\n", k, s[k].size());
// debug("%lld [%lld] %lld | s %lld %lld\n", k, dfn_xu[k], (*t), a[k].s, a[k].mx);
if(t != s[k].begin()) {
/* debug("? %lld [%lld]\n", l, dfn_xu[l]); */
--t; a[k].mx += max(0ll, (*t));
// debug("\t\t next %lld === %lld\n", *t, a[k].mx);
}
return ;
}
if(x <= mid) update(ls, l, mid, x, y, o);
else update(rs, mid+1, r, x, y, o);
push_up(k);
}
node quemx(int k, int l, int r, int x, int y) {
assert(x >= 1 && x <= n);
assert(y >= 1 && y <= n);
if(l >= x && r <= y) return a[k];
node a, b; a.mem(); b.mem();
if(x <= mid) a = quemx(ls, l, mid, x, y); else return quemx(rs, mid+1, r, x, y);
if(y >= mid+1) b = quemx(rs, mid+1, r, x, y); else return a;
return a + b;
}
pair<int, int> queRmx(int k, int l, int r, int x, int y) {
assert(x >= 1 && x <= n);
assert(y >= 1 && y <= n);
if(l >= x && r <= y) return {a[k].s, a[k].L};
pair<int, int> ta, tb, t;
if(x <= mid) ta = queRmx(ls, l, mid, x, y);
else return queRmx(rs, mid + 1, r, x, y);
if(y >= mid + 1) tb = queRmx(rs, mid + 1, r, x, y);
else return ta;
return {ta.fi + tb.fi, max(ta.se, ta.fi + tb.se)};
}
#undef ls
#undef rs
#undef mid
}Seg;
namespace Tree {
void dfs(int x, int fa) {
dep[x] = dep[fa] + a[x]; w[x] = 1; F[x] = fa;
for(int y : G[x]) if(y != fa) {
dfs(y, x); w[x] += w[y];
debug("%d : %d | %lld")
if(w[y] > w[son[x]]) son[x] = y;
}
// debug("%lld : %lld\n", x, son[x]);
}
int dfs2(int x, int fa, int Top) {
top[x] = Top; dfn[x] = ++tot; Ed[x] = x; dfn_xu[tot] = x;
// debug("%d ", x);
if(son[x]) Ed[x] = dfs2(son[x], x, Top);
for(int y : G[x]) if(y != fa && y != son[x]) { dfs2(y, x, y); }
return Ed[x];
}
void dfs3(int x, int fa) {
for(int y : G[x]) if(y != fa) { dfs3(y, x); }
if(x == top[x]) {
int qmx = Seg.quemx(1, 1, n, dfn[x], dfn[Ed[x]]).mx;
ans_set.insert(qmx);
auto qR = Seg.queRmx(1, 1, n, dfn[x], dfn[Ed[x]]);
// debug("%lld : [%lld %lld] %lld | %lld fa %lld\n", x, dfn[x], dfn[Ed[x]], qmx, qR.se, fa);
if(fa) { Seg.update(1, 1, n, dfn[fa], qR.se, 1); }
}
}
void Main() {
for(i=1; i<n; ++i) {
u = read(); v = read();
G[u].pb(v); G[v].pb(u);
}
for(i=1; i<=n; ++i) a[i] = read();
dfs(1, 0); dfs2(1, 0, 1);
Seg.build(1, 1, n, a);
// for(i = 1; i <= n; ++i) debug("%d ", dfn[i]);
// for(i = 1; i <= n; ++i) debug("%d ", top[i]); debug("\n");
// for(i = 1; i <= n; ++i) debug("%d ", Ed[i]); debug("\n");
dfs3(1, 0);
}
}
namespace Operation {
void Update(int x, int y) {
stack<int>z;
int k = x; x = top[x];
// printf("# %lld\n", x);
while(1) { /*assert(x>=1 && x<=n); */
z.push(x); if(!F[x]) break; x = F[x]; x = top[x]; }
while(!z.empty()) {
// z.push(x);
x = z.top(); z.pop();
int qmx = Seg.quemx(1, 1, n, dfn[x], dfn[Ed[x]]).mx;
ans_set.erase(ans_set.find(qmx));
// debug("Erase : %lld (%lld %lld)\n", qmx, x, F[x]);
auto qR = Seg.queRmx(1, 1, n, dfn[x], dfn[Ed[x]]);
if(F[x]) { Seg.update(1, 1, n, dfn[F[x]], qR.se, -1); }
// else break;
// x = F[x]; x = top[x];
}
x = k;
Seg.add(1, 1, n, dfn[x], y);
x = top[x];
// while(!z.empty()) {
while(1) {
// x = z.top(); z.pop();
int qmx = Seg.quemx(1, 1, n, dfn[x], dfn[Ed[x]]).mx;
ans_set.insert(qmx);
auto topmx = Seg.queRmx(1, 1, n, dfn[x], dfn[Ed[x]]);
// debug("Insert : %lld (%lld %lld) topmx %lld\n", qmx, x, F[x], topmx.se);
if(F[x]) { Seg.update(1, 1, n, dfn[F[x]], topmx.se, 1); }
else break;
x = F[x]; x = top[x];
}
}
int Qans() {
auto t = ans_set.end(); --t;
return (*t);
}
void Main() {
int cnt = 0;
while(q--) {
op = read();
// printf("%d : ", op);
// if(q%100 == 0)
// printf("%lld : ", ++cnt);
if(q<=80769) debug("%d\n", q);
if(op == 1) {
printf("%lld\n", Qans());
}
if(op == 2) {
u = read();
Update(u, 1e16);
int k = Qans();
// debug("%lld\n", k);
printf("%lld\n", k - (int)1e16 + a[u]);
Update(u, a[u]);
}
if(op == 3) {
u = read(); v = read();
Update(u, v); a[u] = v;
}
// debug("----------------------\n");
}
}
}
signed main()
{
freopen("taffy.in", "r", stdin);
freopen("taffy.out", "w", stdout);
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
// srand(time(NULL));
// T=read();
// while(T--) {
//
// }
n = read(); q = read();
Tree :: Main();
Operation :: Main();
return 0;
}