zoukankan      html  css  js  c++  java
  • 洛谷P3178 [HAOI2015]树上操作 (树链剖分)

    题目链接:

    https://www.luogu.com.cn/problem/P3178

    思路:

    树剖板子

    代码:

    #include <bits/stdc++.h>
    #define ls node<<1
    #define rs node<<1|1
    using namespace std;
    typedef long long ll;
    const int MAXN=2e5+5;
    ll n,m;
    ll head[MAXN],tot;
    struct node
    {
        ll to,nxt;
    }e[MAXN<<1];
    void add(ll x,ll y)
    {
        e[tot].to=y;e[tot].nxt=head[x];head[x]=tot++;
    }
    void add_edge(ll x,ll y){add(x,y);add(y,x);}
    ll dep[MAXN],f[MAXN],sz[MAXN],son[MAXN];
    void dfs(int u,int fa)
    {
        dep[u]=dep[fa]+1;sz[u]=1;f[u]=fa;
        for(int i=head[u];~i;i=e[i].nxt)
        {
            ll v=e[i].to;
            if(v!=fa)
            {
                dfs(v,u);
                sz[u]+=sz[v];
                if(sz[v]>sz[son[u]])
                    son[u]=v;
            }
        }
    }
    ll top[MAXN],id[MAXN],val[MAXN],a[MAXN],cnt;
    void dfs2(ll u,ll t)
    {
        top[u]=t;id[u]=++cnt;a[cnt]=val[u];
        if(son[u])
            dfs2(son[u],t);
        for(int i=head[u];~i;i=e[i].nxt)
        {
            ll v=e[i].to;
            if(v!=f[u]&&v!=son[u])
                dfs2(v,v);
        }
    }
    ll tree[MAXN<<2],lazy[MAXN<<2];
    void push_up(ll node)
    {
        tree[node]=tree[ls]+tree[rs];
    }
    void build(ll node,ll l,ll r)
    {
        if(l==r){tree[node]=a[l];return;}
        ll mid=(l+r)>>1;
        build(ls,l,mid);build(rs,mid+1,r);
        push_up(node);
    }
    void push_down(ll node,ll l,ll r,ll mid)
    {
        if(lazy[node])
        {
            lazy[ls]+=lazy[node];lazy[rs]+=lazy[node];
            tree[ls]+=lazy[node]*(mid-l+1);tree[rs]+=lazy[node]*(r-mid);
            lazy[node]=0;
        }
    }
    void update(ll node,ll l,ll r,ll x,ll y,ll k)
    {
        if(l>=x&&r<=y)
        {
            lazy[node]+=k;tree[node]+=(r-l+1)*k;return;
        }
        ll mid=(l+r)>>1;
        push_down(node,l,r,mid);
        if(x<=mid)
            update(ls,l,mid,x,y,k);
        if(y>mid)
            update(rs,mid+1,r,x,y,k);
        push_up(node);
    }
    ll query(ll node,ll l,ll r,ll x,ll y)
    {
        if(l>=x&&r<=y)
        {
            //cout<<tree[node]<<endl;
            return tree[node];
        }
        ll mid=(l+r)>>1;
        push_down(node,l,r,mid);
        ll ans=0;
        if(x<=mid)
            ans+=query(ls,l,mid,x,y);
        if(y>mid)
            ans+=query(rs,mid+1,r,x,y);
        return ans;
    }
    ll tree_sum(ll x,ll y)
    {
        ll fx=top[x],fy=top[y];ll ans=0;
        while(fx!=fy)
        {
            if(dep[fx]<dep[fy])swap(x,y),swap(fx,fy);
            ans+=query(1,1,n,id[fx],id[x]);
    
            x=f[fx];fx=top[x];
        }
        if(id[x]>id[y])swap(x,y);
        //cout<<id[x]<<" "<<id[y]<<endl;
        ans+=query(1,1,n,id[x],id[y]);
        return ans;
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&val[i]);
        }
        for(int i=1;i<n;i++)
        {
            ll x,y;scanf("%lld%lld",&x,&y);
            add_edge(x,y);
        }
        dfs(1,0);dfs2(1,1);build(1,1,n);
        while(m--)
        {
            int op;scanf("%d",&op);
            ll x,y;
            if(op==1)
            {
                scanf("%lld%lld",&x,&y);
                update(1,1,n,id[x],id[x],y);
            }
            if(op==2)
            {
                scanf("%lld%lld",&x,&y);
                update(1,1,n,id[x],id[x]+sz[x]-1,y);
            }
            if(op==3)
            {
                scanf("%lld",&x);
                printf("%lld
    ",tree_sum(1,x));
            }
        }
        return 0;
    }
  • 相关阅读:
    android aar Could not find :ucrop-debug2.2.4:.
    OpenGL 实践之贝塞尔曲线绘制
    OpenGL 实现视频编辑中的转场效果
    简单易用的图像解码库介绍 —— stb_image
    博客图床迁移记
    Android 图片加载框架 Glide4.x
    Android 屏幕适配插件 ScreenMatch
    Android .9.png 的介绍
    Android 网络框架 Retrofit2
    Android 网络框架 OKHttp3
  • 原文地址:https://www.cnblogs.com/ljxdtc666/p/12594372.html
Copyright © 2011-2022 走看看