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\n",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
*/