A
B

U159634 [BZOJ3786]星系探索

U159634 [BZOJ3786]星系探索

// U159634 [BZOJ3786]星系探索
#include<bits/stdc++.h>
#define int long long
#define Blue_Archive return 0
#define con putchar(' ')
#define end putchar('\n')
#define ls(x) t[x].ch[0]
#define rs(x) t[x].ch[1]
#define add(x,v) to[++ tot] = v,nxt[tot] = h[x],h[x] = tot
#define update(x) t[x].siz = t[ls(x)].siz + t[rs(x)].siz + 1,t[x].sum = t[ls(x)].sum + t[rs(x)].sum + t[x].val,t[x].pds = t[ls(x)].pds + t[rs(x)].pds + t[x].pd
using namespace std;
const int N = 1e5 + 3;

int n;
int m;
int tot;
int cnt;
int top;
int root;
int w[N];
int h[N << 1];
int to[N << 1];
int nxt[N << 1];
int dfn[N << 1];
int rdfn[N << 1];
int ldfn[N << 1];

char op;

struct miku
{
	int fa;
	int pd;
	int pds;
	int laz;
	int val;
	int pri;
	int siz;
	int sum;
	int ch[2];
}t[N << 4];

inline int read()
{
	int x = 0;
	char c = getchar_unlocked();
	for(;!isdigit(c);c = getchar_unlocked());
	for(;isdigit(c);x = x * 10 + c - 48,c = getchar_unlocked());
	return x;
}

inline void write(int x)
{
	if(x < 0) putchar_unlocked('-'),x = -x;
	if(x > 9) write(x / 10);
	putchar_unlocked(x % 10 + '0');
	return;
}

inline void dfs(int x,int fa)
{
	ldfn[++ cnt] = w[x];
	for(int i = h[x];i;i = nxt[i])
	{
		if(to[i] == fa) continue;
		dfs(to[i],x);
	}
	ldfn[++ cnt] = -w[x];
}

inline void link(int x,int c,int y)
{
	t[x].ch[c] = y;
	if(y) t[y].fa = x;
	update(x);
}

inline void down(int x)
{
	if(ls(x))
	{
		t[ls(x)].laz += t[x].laz;
		t[ls(x)].sum += t[x].laz * t[ls(x)].pds;
		t[ls(x)].val += t[x].laz * t[ls(x)].pd;
	}
	if(rs(x))
	{
		t[rs(x)].laz += t[x].laz;
		t[rs(x)].sum += t[x].laz * t[rs(x)].pds;
		t[rs(x)].val += t[x].laz * t[rs(x)].pd;
	}
	t[x].laz = 0;
}

inline int build(int x,int y)
{
	t[++ top].pd = y;
	t[top].pds = y;
	t[top].val = x;
	t[top].sum = x;
	t[top].siz = 1;
	t[top].pri = rand();
	return top;
}

inline void split(int now,int k,int &l,int &r)
{
	t[now].fa = 0;
	if(!now)
	{
		l = r = 0;
		return;
	}
	down(now);
	if(t[ls(now)].siz < k)
	{
		l = now;
		split(rs(now),k - t[ls(now)].siz - 1,rs(now),r);
		link(l,1,rs(l));
	}
	else
	{
		r = now;
		split(ls(now),k,l,ls(now));
		link(r,0,ls(r));
	}
	update(now);//!!!!!
}

inline int meg(int l,int r)//合并(返回合并后的根节点)
{
	if(!l || !r) return l | r;
	if(t[l].pri < t[r].pri)
	{
		down(l);
		link(l,1,meg(rs(l),r));
		update(l);
		return l;
	}
	else
	{
		down(r);
		link(r,0,meg(l,ls(r)));
		update(r);
		return r;
	}
}

inline int rnk(int x)
{
    int c = 1,ans = 0;
    while(x)
    {
        if(c) ans += t[ls(x)].siz + 1;
        c = (rs(t[x].fa) == x);
        x = t[x].fa;
    }
    return ans;
}

inline void ins(int x,int v)
{
	int l,r,p;
	split(root,rnk(rdfn[x]),l,r);
	split(l,rnk(dfn[x]) - 1,l,p);
	t[p].laz += v;
	t[p].sum += v * t[p].pds;
	t[p].val += v * t[p].pd;
	root = meg(l,meg(p,r));
}

inline int query(int x)
{
	int l,r;
	split(root,rnk(dfn[x]),l,r);
	int ans = t[l].sum;
	root = meg(l, r);
	return ans;
}

inline void change(int x, int y)
{
	int fa,l,p,r;
	split(root,rnk(rdfn[x]),l,r);
	split(l,rnk(dfn[x]) - 1,l,p);
	l = meg(l, r);
	split(l,rnk(dfn[y]),fa,l);
	root = meg(meg(fa,p),l);
}

inline void dfs(int x)
{
	root = meg(root,dfn[x] = build(w[x], 1));
	for(int i = h[x];i;i = nxt[i]) dfs(to[i]);
	root = meg(root,rdfn[x] = build(-w[x], -1));
}

signed main()
{
	n = read();
	for(int i = 2,x;i <= n;i ++)
	{
		x = read();
		add(x,i);
	}
	for(int i = 1;i <= n;i ++) w[i] = read();
	dfs(1,0);
	dfs(1);
	m = read();
	for(int i = 1,x,y;i <= m;i ++)
	{
		// while(op < 'A' && op > 'Z') op = getchar();
		cin >> op;
		if(op == 'Q')//到根的最短路径节点权值和
		{
			x = read();
			write(query(x)),end;
		}
		if(op == 'C')
		{
			x = read(),y = read();
			change(x,y);
		}
		if(op == 'F')
		{
			x = read(),y = read();
			ins(x,y);
		}
	}
	Blue_Archive;
}
posted @ 2025-08-28 16:05  MyShiroko  阅读(10)  评论(0)    收藏  举报