zoukankan      html  css  js  c++  java
  • 【BZOJ4034】树上操作(HAOI2015)-树链剖分

    测试地址:树上操作
    做法:其实是很明显的树链剖分了,单点修改+子树修改+路径询问,写这个是为了复健,因为感觉好久没写这种代码量大的题了,结果交上去一发直接过,美滋滋。
    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    using namespace std;
    int n,m;
    int tot=0,first[100010]={0},in[100010]={0},out[100010]={0},tim=0;
    int dep[100010],siz[100010],son[100010],fa[100010],pos[100010],top[100010];
    ll sum[400010],tag[400010],val[100010];
    struct edge {int v,next;} e[200010];
    
    void insert(int a,int b)
    {
        e[++tot].v=b;
        e[tot].next=first[a];
        first[a]=tot;
    }
    
    void dfs1(int v)
    {
        siz[v]=1;son[v]=0;
        for(int i=first[v];i;i=e[i].next)
            if (e[i].v!=fa[v])
            {
                fa[e[i].v]=v;
                dep[e[i].v]=dep[v]+1;
                dfs1(e[i].v);
                if (siz[son[v]]<siz[e[i].v]) son[v]=e[i].v;
                siz[v]+=siz[e[i].v];
            }
    }
    
    void dfs2(int v,int p)
    {
        top[v]=p;
        pos[++tim]=v;
        in[v]=tim;
        if (son[v]) dfs2(son[v],p);
        for(int i=first[v];i;i=e[i].next)
            if (e[i].v!=fa[v]&&e[i].v!=son[v])
                dfs2(e[i].v,e[i].v);
        out[v]=tim;
    }
    
    void pushdown(int no,int l,int r)
    {
        if (tag[no]!=0)
        {
            int mid=(l+r)>>1;
            tag[no<<1]+=tag[no];
            tag[no<<1|1]+=tag[no];
            sum[no<<1]+=((ll)(mid-l+1))*tag[no];
            sum[no<<1|1]+=((ll)(r-mid))*tag[no];
            tag[no]=0;
        }
    }
    
    void pushup(int no)
    {
        sum[no]=sum[no<<1]+sum[no<<1|1];
    }
    
    void buildtree(int no,int l,int r)
    {
        if (l==r)
        {
            sum[no]=val[pos[l]];
            return;
        }
        int mid=(l+r)>>1;
        buildtree(no<<1,l,mid);
        buildtree(no<<1|1,mid+1,r);
        pushup(no);
    }
    
    void add(int no,int l,int r,int s,int t,ll val)
    {
        if (l>=s&&r<=t)
        {
            tag[no]+=val;
            sum[no]+=((ll)(r-l+1))*val;
            return;
        }
        int mid=(l+r)>>1;
        pushdown(no,l,r);
        if (s<=mid) add(no<<1,l,mid,s,t,val);
        if (t>mid) add(no<<1|1,mid+1,r,s,t,val);
        pushup(no);
    }
    
    ll segquery(int no,int l,int r,int s,int t)
    {
        if (l>=s&&r<=t)
        {
            return sum[no];
        }
        int mid=(l+r)>>1;
        ll ss=0;
        pushdown(no,l,r);
        if (s<=mid) ss+=segquery(no<<1,l,mid,s,t);
        if (t>mid) ss+=segquery(no<<1|1,mid+1,r,s,t);
        pushup(no);
        return ss;
    }
    
    ll query(int x,int y)
    {
        ll ans=0;
        while(top[x]!=top[y])
        {
            if (dep[top[x]]<dep[top[y]]) swap(x,y);
            ans+=segquery(1,1,n,in[top[x]],in[x]);
            x=fa[top[x]];
        }
        if (dep[x]<dep[y]) swap(x,y);
        ans+=segquery(1,1,n,in[y],in[x]);
        return ans;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%lld",&val[i]);
        for(int i=1;i<n;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            insert(a,b);insert(b,a);
        }
    
        fa[1]=siz[0]=0;
        dep[1]=1;
        dfs1(1);
        dfs2(1,1);
        buildtree(1,1,n);
    
        for(int i=1;i<=m;i++)
        {
            int op,a;
            ll d;
            scanf("%d",&op);
            if (op==1)
            {
                scanf("%d%lld",&a,&d);
                add(1,1,n,in[a],in[a],d);
            }
            if (op==2)
            {
                scanf("%d%lld",&a,&d);
                add(1,1,n,in[a],out[a],d);
            }
            if (op==3)
            {
                scanf("%d",&a);
                printf("%lld
    ",query(1,a));
            }
        }
    
        return 0;
    }
    
  • 相关阅读:
    Leetcode Binary Tree Level Order Traversal
    Leetcode Symmetric Tree
    Leetcode Same Tree
    Leetcode Unique Paths
    Leetcode Populating Next Right Pointers in Each Node
    Leetcode Maximum Depth of Binary Tree
    Leetcode Minimum Path Sum
    Leetcode Merge Two Sorted Lists
    Leetcode Climbing Stairs
    Leetcode Triangle
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793613.html
Copyright © 2011-2022 走看看