大意:
单点修改,子树查询;
思路:
dfs,将树掰成线性的;
然后无脑树状数组即可
水水更健康~
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(x) x&(-x)
const ll N=1e6+10;
ll n,m,k;
ll a,b,c;
ll tr[N];
ll mas[N];//初始权值
struct ty
{
ll t,next;
}edge[N<<1];
ll head[N];
ll cntt=0;
void add(ll a,ll b)
{
edge[++cntt].t=b;
edge[cntt].next=head[a];
head[a]=cntt;
}
ll l[N],r[N];//代表其子树的对应数字范围
ll cnt=0;
void dfs(ll p,ll fa)
{
l[p]=++cnt;
for(int i=head[p];i!=-1;i=edge[i].next)
{
ll y=edge[i].t;
if(y==fa) continue;
dfs(y,p);
}
r[p]=cnt;//右界
}
void adds(ll x,ll y)
{
while(x<=n)
{
tr[x]+=y;
x+=lowbit(x);
}
}
ll sum(ll x)
{
ll ans=0;
while(x)
{
ans+=tr[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
scanf("%lld%lld%lld",&n,&m,&k);
memset(head,-1,sizeof head);
for(int i=1;i<=n;++i) scanf("%lld",&mas[i]);
for(int i=1;i<=n-1;++i)
{
scanf("%lld%lld",&a,&b);
add(a,b);
add(b,a);
}
dfs(k,-1);
for(int i=1;i<=n;++i) adds(l[i],mas[i]);//初始值
while(m--)
{
scanf("%lld%lld",&a,&b);
if(a==1)
{
scanf("%lld",&c);
adds(l[b],c);
continue;
}
//cin>>b;
printf("%lld\n",sum(r[b])-sum(l[b]-1));
}
return 0;
}