BZOJ 1984月下“毛景树” LCT维护边权_下传标记
Code:
#include <bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 100050
#define inf 0x3f
using namespace std;
int n;
char str[10];
namespace LCT
{
#define lson ch[x][0]
#define rson ch[x][1]
int maxv[maxn << 1], tag[maxn << 1], rev[maxn << 1], addv[maxn << 1], val[maxn << 1], siz[maxn << 1], f[maxn << 1], sta[maxn << 1], ch[maxn << 1][2];
int isRoot(int x)
{
return !(ch[f[x]][0] == x || ch[f[x]][1] == x);
}
int get(int x)
{
return ch[f[x]][1] == x;
}
void mark_tag(int x, int delta)
{
if(!x) return;
addv[x] = 0;
tag[x] = (siz[x] ? delta : 0);
maxv[x] = (siz[x] ? delta : 0);
if(x > n) val[x] = delta;
}
void mark_add(int x, int delta)
{
if(!x) return;
addv[x] += (siz[x] ? delta : 0);
maxv[x] += (siz[x] ? delta : 0);
if(x > n) val[x] += delta;
}
void mark_rev(int x)
{
if(!x) return;
swap(lson, rson), rev[x] ^= 1;
}
void pushup(int x)
{
maxv[x] = max(val[x], max(maxv[lson], maxv[rson]));
siz[x] = (x > n) + siz[lson] + siz[rson];
}
void pushdown(int x)
{
if(tag[x]) mark_tag(lson, tag[x]), mark_tag(rson, tag[x]), tag[x] = 0;
if(addv[x]) mark_add(lson, addv[x]), mark_add(rson, addv[x]), addv[x] = 0;
if(rev[x]) mark_rev(lson), mark_rev(rson), rev[x] = 0;
}
void rotate(int x)
{
int old = f[x], fold = f[old], which = get(x);
if(!isRoot(old)) ch[fold][ch[fold][1] == old] = x;
ch[old][which] = ch[x][which ^ 1], f[ch[old][which]] = old;
ch[x][which ^ 1] = old, f[old] = x, f[x] = fold;
pushup(old), pushup(x);
}
void splay(int x)
{
int u = x, v = 0;
sta[++v] = u;
while(!isRoot(u)) sta[++v] = f[u], u = f[u];
while(v) pushdown(sta[v--]);
u = f[u];
for(int fa; (fa = f[x]) != u; rotate(x))
if(f[fa] != u) rotate(get(fa) == get(x) ? fa : x);
}
void Access(int x)
{
int y = 0;
while(x) splay(x), rson = y, pushup(x), y = x, x = f[x];
}
void MakeRoot(int x)
{
Access(x), splay(x), mark_rev(x);
}
// y is new root
void split(int x, int y)
{
MakeRoot(x), Access(y), splay(y);
}
void link(int x, int y)
{
MakeRoot(y), f[y] = x;
}
};
int main()
{
// setIO("input");
LCT :: maxv[0] = -inf;
scanf("%d",&n);
for(int i = 1; i < n; ++i)
{
int u, v, w;
scanf("%d%d%d",&u,&v,&w);
LCT :: val[i + n] = w;
LCT :: link(u, i + n);
LCT :: link(i + n, v);
}
while(1)
{
scanf("%s",str);
int u, v, k, w;
if(str[0] == 'A')
{
scanf("%d%d%d",&u,&v,&w), LCT :: split(u, v), LCT :: mark_add(v, w);
}
if(str[0] == 'M')
{
scanf("%d%d",&u,&v), LCT :: split(u, v), printf("%d\n",LCT :: maxv[v]);
}
if(str[1] == 'o')
{
scanf("%d%d%d",&u,&v,&w), LCT :: split(u, v), LCT :: mark_tag(v, w);
}
if(str[1] == 'h')
{
scanf("%d%d",&k,&w);
LCT :: Access(k + n), LCT :: splay(k + n), LCT :: val[k + n] = w, LCT :: pushup(k + n);
}
if(str[0] == 'S') break;
}
return 0;
}