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;
}
与你的日常,便是奇迹

浙公网安备 33010602011771号