• bzoj 4034(DFS序+线段树)


    这个题多了一个操作难度直线上升,看完题解才会写

     有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个
    操作,分为三种:
    操作 1 :把某个节点 x 的点权增加 a 。
    操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
    操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

    按照题意:记录其DFS序,然后进栈是正,出栈为负,利用线段树进行更新

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    #include <vector>
    #include <stack>
    using namespace std;
    typedef long long LL;
    const int N = 800005;
    struct Edge
    {
        int v,next;
    } edge[N<<1];
    int head[N],tot,cnt;
    int val[N];
    int in[N],out[N];
    LL tree[N<<2],lazy[N<<2],seg[N];
    int flag[N<<2];
    int io[N];
    void addEdge(int u,int v)
    {
        edge[tot].v = v,edge[tot].next = head[u],head[u] = tot++;
    }
    void init()
    {
        memset(head,-1,sizeof(head));
        memset(val,0,sizeof(val));
        memset(lazy,0,sizeof(lazy));
        memset(io,0,sizeof(io));
        memset(seg,0,sizeof(seg));
        tot = cnt = 0;
    }
    void dfs(int u,int fa)
    {
        seg[in[u] = ++cnt] = (LL)val[u];
        io[cnt] = 1;
        for(int i=head[u]; i!=-1; i=edge[i].next)
        {
            if(edge[i].v != fa)
            {
                dfs(edge[i].v,u);
            }
        }
        seg[out[u] = ++cnt] = (LL)(-val[u]);
        io[cnt] = -1;
    }
    
    void pushup(int idx)
    {
        tree[idx] = tree[idx<<1]+tree[idx<<1|1];
        return;
    }
    void pushdown(int idx)
    {
        if(lazy[idx])
        {
            tree[idx << 1] +=  flag[idx<<1]*lazy[idx];
            tree[idx << 1 | 1] += flag[idx<<1|1]*lazy[idx];
            lazy[idx << 1] += lazy[idx];
            lazy[idx << 1 | 1] += lazy[idx];
            lazy[idx] = 0;
        }
        return;
    }
    void build(int l,int r,int idx)
    {
        if(l==r)
        {
            tree[idx] = seg[l];
            if(io[l]>0) flag[idx] = 1;
            else flag[idx] = -1;
            return;
        }
        int mid = (l+r)>>1;
        build(l,mid,idx<<1);
        build(mid+1,r,idx<<1|1);
        pushup(idx);
        flag[idx] = flag[idx<<1] + flag[idx<<1|1];
    }
    void update(int l,int r,int L,int R,int idx,int val)
    {
        if(l>=L&&r<=R)
        {
            tree[idx] =tree[idx] + (LL)flag[idx]*val;
            lazy[idx] =lazy[idx] + (LL)val;
            return;
        }
        int mid = (l+r)>>1;
        pushdown(idx);
        if(mid>=L) update(l,mid,L,R,idx<<1,val);
        if(mid<R) update(mid+1,r,L,R,idx<<1|1,val);
        pushup(idx);
    }
    LL query(int l,int r,int L,int R,int idx){
        if(l>=L&&r<=R)
        {
            return tree[idx];
        }
        int mid = (l+r)>>1;
        LL sum = 0;
        pushdown(idx);
        if(mid>=L) sum+=query(l,mid,L,R,idx<<1);
        if(mid<R) sum+=query(mid+1,r,L,R,idx<<1|1);
        return sum;
    }
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            init();
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&val[i]);
            }
            for(int i=1; i<n; i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                addEdge(u,v);
                addEdge(v,u);
            }
            dfs(1,0);
            build(1,2*n,1);
            while(m--)
            {
                int op,x,y;
                scanf("%d",&op);
                if(op==1)
                {
                    scanf("%d%d",&x,&y);
                    update(1,2*n,in[x],in[x],1,y);
                    update(1,2*n,out[x],out[x],1,y);
                }else if(op==2){
                    scanf("%d%d",&x,&y);
                    update(1,2*n,in[x],out[x],1,y);
                }else{
                    scanf("%d",&x);
                    LL sum = query(1,2*n,1,in[x],1);
                    printf("%lld
    ",sum);
                }
            }
        }
    }
  • 相关阅读:
    胃食管反流性咳嗽发病机制的研究进展
    胃食管反流之 SAP分析( in the Ohmega software)
    重做贪吃蛇 万向移动型 蛇的移动和吃食部分C# wpf版
    C# 根据波形图片,提取测试数据点 Winform
    C# EF 使用sqlite 数据库出现表名出现dbo的坑
    C# 方块热力图
    C# 使用 运算符重载 隐式转换 对Point进行加减计算
    简单实现TCP客户端重连机制
    图像sensor的特性和驱动解析
    ISP图像质量调节相关资料
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5965981.html
Copyright © 2020-2023  润新知