D - Snacks HDU - DFS序-线段树

  • D - Snacks

  •  HDU - 5692 
  • 注意val值是各个点到0的距离然后dfs序跑一边标号之后建树区间更新区间查询最大值即可
  • #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<stdio.h>
    using namespace std;
    #define lson root << 1,l, mid
    #define rson root << 1 | 1,mid + 1, r
    #define maxn 100861
    #define ll long long
    int t,n,m,x,y,op,cnt,id[maxn];
    int lef[maxn],head[maxn];
    ll dis[maxn],a[maxn];
    int rig[maxn],tot;
    struct edg
    {
        int v,to;
    } edge[maxn*4];
    struct node
    {
        int l,r;
        ll val,lazy;
    } tree[maxn*4];
    void add(int u,int v)
    {
        edge[++cnt].v=v;
        edge[cnt].to=head[u];
        head[u]=cnt;
        edge[++cnt].v=u;
        edge[cnt].to=head[v];
        head[v]=cnt;
    }
    void init()
    {
        tot=cnt=0;
        memset(head,-1,sizeof(head));
        memset(dis,0,sizeof(dis));
    }
    void dfs(int u,int pre)
    {
        lef[u]=++tot;
        id[tot]=u;
        for(int i=head[u]; i!=-1; i=edge[i].to)
        {
            if(edge[i].v!=pre)
            {
                dis[edge[i].v]=dis[u]+a[edge[i].v];
                dfs(edge[i].v,u);
            }
        }
        rig[u]=tot;
    }
    void push_up(int root)
    {
        tree[root].val=max(tree[root<<1].val,tree[(root<<1)|1].val);
        return ;
    }
    void push_down(int root)
    {
        if(tree[root].lazy!=0)
        {
            tree[root<<1].val+=tree[root].lazy;
            tree[root<<1|1].val+=tree[root].lazy;
            tree[root<<1].lazy+=tree[root].lazy;
            tree[root<<1|1].lazy+=tree[root].lazy;
            tree[root].lazy=0;
        }
        return ;
    }
    void build(int root,int l,int r)
    {
        tree[root].l=l;
        tree[root].r=r;
        tree[root].lazy=0;
        if(l==r)
        {
            tree[root].val=dis[id[l]];
            return ;
        }
        int mid=(l+r)/2;
        build(lson);
        build(rson);
        push_up(root);
    }
    void updata(int root,int l,int r,int ad)
    {
        if(tree[root].l==l&&tree[root].r==r)
        {
            tree[root].val+=ad;
            tree[root].lazy+=ad;
            return ;
        }
        push_down(root);
        int mid=(tree[root].l+tree[root].r)/2;
        if(r<=mid)updata(root<<1,l,r,ad);
        else if(l>mid)updata(root<<1|1,l,r,ad);
        else
        {
            updata(root<<1,l,mid,ad);
            updata(root<<1|1,mid+1,r,ad);
        }
        push_up(root);
    }
    ll query(int root,int l,int r)
    {
        if(tree[root].l==l&&tree[root].r==r)
            return tree[root].val;
        push_down(root);
        int mid=(tree[root].l+tree[root].r)/2;
        if(r<=mid)return query(root<<1,l,r);
        else if(l>mid)return query(root<<1|1,l,r);
        else return max(query(root<<1,l,mid),query(root<<1|1,mid+1,r));
    }
    int main()
    {
        scanf("%d",&t);
        for(int cas=1; cas<=t; cas++)
        {
            init();
            printf("Case #%d:\n",cas);
            scanf("%d%d",&n,&m);
            for(int i=1; i<n; i++)
            {
                scanf("%d%d",&x,&y);
                add(x,y);
            }
            for(int i=0; i<n; i++)
                scanf("%lld",&a[i]);
            dis[0]=a[0];
            dfs(0,-1);
            build(1,1,tot);
            while(m--)
            {
                scanf("%d",&op);
                if(op==0)
                {
                    scanf("%d%d",&x,&y);
                    updata(1,lef[x],rig[x],y-a[x]);
                    a[x]=y;
                }
                else if(op==1)
                {
                    scanf("%d",&x);
                    printf("%lld\n",query(1,lef[x],rig[x]));
                }
            }
        }
        return 0;
    }
    

猜你喜欢

转载自blog.csdn.net/BePosit/article/details/83211145