题目描述
题解
单点修改+树链查询转化成子树修改+单点查询
写链剖也嗞磁
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define N 100005
int n,dfs_clock;
int tot,point[N],nxt[N*2],v[N*2];
int in[N],out[N],sum[N*4],delta[N*4];
void add(int x,int y)
{
++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;
}
void dfs(int x,int fa)
{
in[x]=++dfs_clock;
for (int i=point[x];i;i=nxt[i])
if (v[i]!=fa)
dfs(v[i],x);
out[x]=dfs_clock;
}
void update(int now)
{
sum[now]=sum[now<<1]+sum[now<<1|1];
}
void pushdown(int now,int l,int r,int mid)
{
if (delta[now])
{
sum[now<<1]+=delta[now]*(mid-l+1);delta[now<<1]+=delta[now];
sum[now<<1|1]+=delta[now]*(r-mid);delta[now<<1|1]+=delta[now];
delta[now]=0;
}
}
void change(int now,int l,int r,int lr,int rr)
{
int mid=(l+r)>>1;
if (lr<=l&&r<=rr)
{
sum[now]+=r-l+1;
++delta[now];
return;
}
pushdown(now,l,r,mid);
if (lr<=mid) change(now<<1,l,mid,lr,rr);
if (mid+1<=rr) change(now<<1|1,mid+1,r,lr,rr);
}
int query(int now,int l,int r,int x)
{
int mid=(l+r)>>1;
if (l==r) return sum[now];
pushdown(now,l,r,mid);
if (x<=mid) return query(now<<1,l,mid,x);
else return query(now<<1|1,mid+1,r,x);
}
int main()
{
scanf("%d",&n);
for (int i=1;i<n;++i)
{
int x,y;scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
dfs(1,0);
for (int i=1;i<=n;++i)
{
int x;scanf("%d",&x);
printf("%d\n",query(1,1,n,in[x]));
change(1,1,n,in[x],out[x]);
}
}