dfs序处理的一类问题为查询子树权值和
在这里第一次使用了临界表存图
邻接表适用于稀疏图 对于重边自环问题可以代替临界矩阵
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
using namespace std;
struct node1//´æÊ÷
{
long long num;
int in,out;
}a[1000005];
int s[2000005];
int e[2000005];
int firs[2000005];
int nex[2000005];
long long nu[1000005];
bool vis[1000005];
int ti=0;
void dfs(int x)//dfs
{
a[x].in=++ti;
nu[a[x].in]=a[x].num;
for(int i=firs[x];i!=-1;i=nex[i])
{
if(vis[e[i]]==0)
{
vis[e[i]]=1;
dfs(e[i]);
}
}
a[x].out=ti;
return ;
}
int cnt=1;
void ad(int x,int y)
{
s[cnt]=x;
e[cnt]=y;
nex[cnt]=firs[x];
firs[x]=cnt;
cnt++;
}
struct node
{
int l,r;
long long sum;
} tree[2000004];
void build(int l,int r,int root)
{
tree[root].l=l;
tree[root].r=r;
if(l==r)
tree[root].sum=nu[l];
else
{
int mid=(l+r)/2;
build(l,mid,root*2);
build(mid+1,r,root*2+1);
tree[root].sum=tree[root*2].sum+tree[root*2+1].sum;
}
}
long long qurey(int l,int r,int root)
{
if(l==tree[root].l&&r==tree[root].r)
return tree[root].sum;
int mid=(tree[root].l+tree[root].r)/2;
if(r<=mid)
return qurey(l,r,root*2);
else if(l>mid)
return qurey(l,r,root*2+1);
else return qurey(l,mid,root*2)+qurey(mid+1,r,root*2+1);
}
void add(int root,int k,int v)
{
if(tree[root].l==k&&tree[root].r==k)
{
tree[root].sum+=v;
return ;
}
int mid=(tree[root].l+tree[root].r)/2;
if(k<=mid)
add(root*2,k,v);
else
add(root*2+1,k,v);
tree[root].sum=tree[root*2].sum+tree[root*2+1].sum;
}
int main()
{
memset(firs,-1,sizeof(firs));
memset(nex,-1,sizeof(nex));
//freopen("in.txt","r",stdin);
int tmp1,tmp2;
memset(vis,0,sizeof(vis));
int n,m,r;
scanf("%d%d%d",&n,&m,&r);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i].num);
for(int i=1;i<n;i++)
{
scanf("%d%d",&tmp1,&tmp2);
ad(tmp1,tmp2);
ad(tmp2,tmp1);
}
vis[r]=1;
dfs(r);
//for(int i=1;i<=5;i++)
//cout<<firs[i]<<" "<<nex[i]<<endl;
int op;
build(1,n,1);
while(m--)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d%d",&tmp1,&tmp2);
add(1,a[tmp1].in,tmp2);
}
else
{
scanf("%d",&tmp1);
printf("%lld
",qurey(a[tmp1].in,a[tmp1].out,1));
}
}
}
/*
5 2 1
1 2 3 4 5
1 2
1 5
2 3
2 4
2 1
2 2
*/