Code:
#include <cstdio>
#include <algorithm>
#define N 200005
#define ll long long
#define lson t[x].ch[0]
#define rson t[x].ch[1]
#define setIO(s) freopen(s".in", "r", stdin)
using namespace std;
int edges, tim, root = 0, top;
int sta[N], hd[N], to[N], nex[N], L[N], R[N], euler[N], val[N];
inline void addedge(int u, int v)
{
nex[++edges] = hd[u], hd[u] = edges, to[edges] = v;
}
struct Stack
{
int x, i;
Stack(int x = 0, int i = 0) : x(x), i(i) {}
}A[N];
struct Node
{
int siz, d, ch[2], f;
ll sum, val, lazy;
}t[N];
inline int get(int x)
{
return t[t[x].f].ch[1] == x;
}
inline void pushup(int x)
{
t[x].siz = t[lson].siz + t[rson].siz + t[x].d;
t[x].sum = t[lson].sum + t[rson].sum + t[x].val;
}
inline void mark(int x, ll v)
{
t[x].val += 1ll * t[x].d * v;
t[x].sum += 1ll * t[x].siz * v;
t[x].lazy += v;
}
inline void pushdown(int x)
{
if(t[x].lazy)
{
if(lson) mark(lson, t[x].lazy);
if(rson) mark(rson, t[x].lazy);
t[x].lazy = 0;
}
}
inline void rotate(int x)
{
int old = t[x].f, fold = t[old].f, which = get(x);
t[old].ch[which] = t[x].ch[which ^ 1], t[t[old].ch[which]].f = old;
t[x].ch[which ^ 1] = old, t[old].f = x, t[x].f = fold;
if(fold) t[fold].ch[t[fold].ch[1] == old] = x;
pushup(old), pushup(x);
}
inline void splay(int x, int &tar)
{
int u = t[tar].f, v = 0;
for(int g = x ; g ; sta[++v] = g, g = t[g].f);
for(int i = v ; i >= 1; --i) pushdown(sta[i]);
for(int fa; (fa = t[x].f) ^ u; rotate(x))
if(t[fa].f ^ u)
rotate(get(fa) == get(x) ? fa: x);
tar = x;
}
void solve()
{
top = 0;
A[++ top] = Stack(1, hd[1]), L[1] = ++tim, t[tim].d = 1, t[tim].val = (ll) val[1];
for( ; top ; )
{
Stack u = A[top];
if(u.i)
{
A[top].i = nex[A[top].i];
A[++ top] = Stack(to[u.i], hd[to[u.i]]);
L[to[u.i]] = ++tim;
t[tim].d = 1, t[tim].val = (ll) val[to[u.i]];
}
else
{
R[u.x] = ++tim;
t[tim].d = -1, t[tim].val = (ll) -val[u.x];
-- top;
}
}
}
int build(int l, int r, int ff)
{
int mid = (l + r) >> 1;
t[mid].f = ff;
if(mid > l) t[mid].ch[0] = build(l, mid - 1, mid);
if(r > mid) t[mid].ch[1] = build(mid + 1, r, mid);
if(mid == 1) t[mid].ch[0] = tim + 1, t[tim + 1].f = mid;
if(mid == tim) t[mid].ch[1] = tim + 2, t[tim + 2].f = mid;
pushup(mid);
return mid;
}
int pre(int x)
{
int g = root;
splay(x, root);
for(x = lson; rson ; pushdown(x), x = rson);
splay(g, root);
return x;
}
int nxt(int x)
{
int g = root;
splay(x, root);
for(x = rson; lson ; pushdown(x), x = lson);
splay(g, root);
return x;
}
int main()
{
// setIO("input");
int n, m, i, j, x, y;
scanf("%d", &n);
for(i = 2; i <= n ; ++i) scanf("%d", &x), addedge(x, i);
for(i = 1; i <= n ; ++i) scanf("%d", &val[i]);
solve(), root = build(1, tim , 0);
scanf("%d", &m);
for(int cas = 1; cas <= m; ++cas)
{
char str[4];
scanf("%s", str);
if(str[0] == 'Q')
{
scanf("%d", &x), splay(L[x], root), printf("%lld\n", t[root].sum - t[t[root].ch[1]].sum);
}
if(str[0] == 'C')
{
scanf("%d%d", &x, &y);
int l = pre(L[x]), r = nxt(R[x]), key, k;
splay(l, root), splay(r, t[root].ch[1]), key = t[t[root].ch[1]].ch[0];
t[key].f = t[t[root].ch[1]].ch[0] = 0, pushup(t[root].ch[1]), pushup(root);
splay(L[y], root), splay(nxt(L[y]), t[root].ch[1]);
t[t[root].ch[1]].ch[0] = key, t[key].f = t[root].ch[1], pushup(t[root].ch[1]), pushup(root);
}
if(str[0] == 'F')
{
scanf("%d%d", &x, &y);
splay(pre(L[x]), root), splay(nxt(R[x]), t[root].ch[1]);
int key = t[t[root].ch[1]].ch[0];
mark(key, 1ll * y);
}
}
return 0;
}
递归:
#include <cstdio>
#include <algorithm>
#define N 200005
#define ll long long
#define lson t[x].ch[0]
#define rson t[x].ch[1]
#define setIO(s) freopen(s".in", "r", stdin)
using namespace std;
int edges, tim, root = 0;
int sta[N], hd[N], to[N], nex[N], L[N], R[N], euler[N], val[N];
inline void addedge(int u, int v)
{
nex[++edges] = hd[u], hd[u] = edges, to[edges] = v;
}
struct Node
{
int siz, d, ch[2], f;
ll sum, val, lazy;
}t[N];
inline int get(int x)
{
return t[t[x].f].ch[1] == x;
}
inline void pushup(int x)
{
t[x].siz = t[lson].siz + t[rson].siz + t[x].d;
t[x].sum = t[lson].sum + t[rson].sum + t[x].val;
}
inline void mark(int x, ll v)
{
t[x].val += 1ll * t[x].d * v;
t[x].sum += 1ll * t[x].siz * v;
t[x].lazy += v;
}
inline void pushdown(int x)
{
if(t[x].lazy)
{
if(lson) mark(lson, t[x].lazy);
if(rson) mark(rson, t[x].lazy);
t[x].lazy = 0;
}
}
inline void rotate(int x)
{
int old = t[x].f, fold = t[old].f, which = get(x);
t[old].ch[which] = t[x].ch[which ^ 1], t[t[old].ch[which]].f = old;
t[x].ch[which ^ 1] = old, t[old].f = x, t[x].f = fold;
if(fold) t[fold].ch[t[fold].ch[1] == old] = x;
pushup(old), pushup(x);
}
inline void splay(int x, int &tar)
{
int u = t[tar].f, v = 0;
for(int g = x ; g ; sta[++v] = g, g = t[g].f);
for(int i = v ; i >= 1; --i) pushdown(sta[i]);
for(int fa; (fa = t[x].f) ^ u; rotate(x))
if(t[fa].f ^ u)
rotate(get(fa) == get(x) ? fa: x);
tar = x;
}
void dfs(int u)
{
L[u] = ++tim;
t[tim].d = 1, t[tim].val = (ll)val[u];
for(int i = hd[u] ; i ; i = nex[i]) dfs(to[i]);
R[u] = ++tim;
t[tim].d = -1, t[tim].val = (ll)-val[u];
}
int build(int l, int r, int ff)
{
int mid = (l + r) >> 1;
t[mid].f = ff;
if(mid > l) t[mid].ch[0] = build(l, mid - 1, mid);
if(r > mid) t[mid].ch[1] = build(mid + 1, r, mid);
if(mid == 1) t[mid].ch[0] = tim + 1, t[tim + 1].f = mid;
if(mid == tim) t[mid].ch[1] = tim + 2, t[tim + 2].f = mid;
pushup(mid);
// printf("%d %d %d\n",mid, t[mid].ch[0], t[mid].ch[1]);
return mid;
}
int pre(int x)
{
int g = root;
splay(x, root);
for(x = lson; rson ; pushdown(x), x = rson);
splay(g, root);
return x;
}
int nxt(int x)
{
int g = root;
splay(x, root);
for(x = rson; lson ; pushdown(x), x = lson);
splay(g, root);
return x;
}
int main()
{
// setIO("input");
int n, m, i, j, x, y;
scanf("%d", &n);
for(i = 2; i <= n ; ++i) scanf("%d", &x), addedge(x, i);
for(i = 1; i <= n ; ++i) scanf("%d", &val[i]);
dfs(1), root = build(1, tim , 0);
scanf("%d", &m);
for(int cas = 1; cas <= m; ++cas)
{
char str[4];
scanf("%s", str);
if(str[0] == 'Q')
{
scanf("%d", &x), splay(L[x], root), printf("%lld\n", t[root].sum - t[t[root].ch[1]].sum);
}
if(str[0] == 'C')
{
scanf("%d%d", &x, &y);
int l = pre(L[x]), r = nxt(R[x]), key, k;
splay(l, root), splay(r, t[root].ch[1]), key = t[t[root].ch[1]].ch[0];
t[key].f = t[t[root].ch[1]].ch[0] = 0, pushup(t[root].ch[1]), pushup(root);
splay(L[y], root), splay(nxt(L[y]), t[root].ch[1]);
t[t[root].ch[1]].ch[0] = key, t[key].f = t[root].ch[1], pushup(t[root].ch[1]), pushup(root);
}
if(str[0] == 'F')
{
scanf("%d%d", &x, &y);
splay(pre(L[x]), root), splay(nxt(R[x]), t[root].ch[1]);
int key = t[t[root].ch[1]].ch[0];
mark(key, 1ll * y);
}
}
return 0;
}