zoukankan      html  css  js  c++  java
  • 【树】【积累】2020牛客多校 A National Pandemic(树剖)

    2020牛客多校 A National Pandemic

    题意

    一棵树 ,三种操作:

    1,一个中心城市 x,所有城市 y 的值+=w-dist(x,y)

    2,将城市x的值与0取min

    3,询问单点的值。

    官方题解

    对于1操作,我们考虑一次修改对y来说会增加w-dis(x,y)

    w-dis(x,y)=w-(dep[x]+dep[y]-2*dep[lca])=w-dep[x]-dep[y]+2dep[lca]

    所以,对于每次1操作,我们将其到根上所有点的cnt+=2,询问的时候那部分就是求它到根的权值和。

    个人

    不是代码不会敲,公式也会,但是就是想不到做法。看了题解才:哦哦哦哦哦!

    唉,比赛时想了半天 一开始觉得是树剖,想做,结果不知道怎么下手,然后绕开树剖继续想。也就没有然后了。

    个人代码:

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    typedef long long ll;
    const int mod=998244353;
    const int inf=0x3f3f3f3f;
    const int maxn=5e4+5;
    const double ep=1e-6;
    
    void read(int&x)
    {
        char c;
        while(!isdigit(c=getchar()));x=c-'0';
        while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-'0';
    }
    int n;
    vector<int>p[maxn];
    int siz[maxn],dep[maxn],fad[maxn],son[maxn];
    int top[maxn],tid[maxn],rnk[maxn],cnt;
    void dfs1(int u,int fa,int d)
    {
        dep[u]=d;fad[u]=fa;siz[u]=1;son[u]=0;
        for(int v:p[u])
        {
            if(v==fa)continue;
            dfs1(v,u,d+1);
            siz[u]+=siz[v];
            if(siz[v]>siz[son[u]])son[u]=v;
        }
    }
    void dfs2(int u,int t)
    {
        top[u]=t;tid[u]=++cnt;rnk[cnt]=u;
        if(!son[u])return;
        dfs2(son[u],t);
        for(int v:p[u])
            if(v!=son[u]&&v!=fad[u])
                dfs2(v,v);
    }
    struct Tr{
        ll sum[maxn<<2],ly[maxn<<2];
        inline void init(){mem(sum,0);mem(ly,0);}
        inline void pdown(int k,int l,int r){
            int mid=(l+r)>>1;
            sum[k<<1]+=ly[k]*(mid-l+1);sum[k<<1|1]+=ly[k]*(r-mid);
            ly[k<<1]+=ly[k];ly[k<<1|1]+=ly[k];
            ly[k]=0;
        }
        void update(int k,int l,int r,int L,int R,int v){
            if(L>r||R<l)return;
            if(L<=l&&r<=R){
                sum[k]+=1ll*v*(r-l+1);ly[k]+=v;
                return;
            }
            if(ly[k])pdown(k,l,r);
            int mid=(l+r)>>1;
            update(k<<1,l,mid,L,R,v);update(k<<1|1,mid+1,r,L,R,v);
            sum[k]=sum[k<<1]+sum[k<<1|1];
    //        printf("update(%d %d)=%lld
    ",l,r,sum[k]);
        }
        ll query(int k,int l,int r,int L,int R){
            if(L>r||R<l)return 0;
            if(L<=l&&r<=R)return sum[k];
            if(ly[k])pdown(k,l,r);
            int mid=(l+r)>>1;
            return query(k<<1,l,mid,L,R)+query(k<<1|1,mid+1,r,L,R);
        }
        void tupdate(int u,int v,int w){
            while(top[u]!=top[v]){
                if(dep[top[u]]<dep[top[v]])swap(u,v);
                update(1,1,n,tid[top[u]],tid[u],w);
                u=fad[top[u]];
            }
            if(dep[u]>dep[v])swap(u,v);
            update(1,1,n,tid[u],tid[v],w);
        }
        ll tquery(int u,int v){
            ll ans=0;
            while(top[u]!=top[v]){
                if(dep[top[u]]<dep[top[v]])swap(u,v);
                ans+=query(1,1,n,tid[top[u]],tid[u]);
                u=fad[top[u]];
            }
            if(dep[u]>dep[v])swap(u,v);
    //        printf("lastans=%lld,query<%d %d>
    ",ans,tid[u],tid[v]);
            ans+=query(1,1,n,tid[u],tid[v]);
            return ans;
        }
    }st;
    ll f[maxn];
    int main()
    {
        int T;
        read(T);
        while(T--)
        {
            int m,u,v;ll all=0,tim=0;
            read(n);read(m);
            for(int i=1;i<=n;i++)p[i].clear(),f[i]=0;
            for(int i=1;i<n;i++)
            {
                read(u);read(v);
                p[u].push_back(v);p[v].push_back(u);
            }
            cnt=0;dfs1(1,0,1);dfs2(1,1);st.init();
    //        for(int i=1;i<=n;i++)printf("%d ",tid[i]);putchar(10);
            int op,x,w;
            while(m--)
            {
                read(op);
                if(op==1){
                    read(x);read(w);all+=w-dep[x];tim++;
                    st.tupdate(1,x,2);
    
                }else if(op==2){
                    read(x);
                    ll ans=all-f[x]-tim*dep[x];
                    ans+=st.tquery(1,x);
                    if(ans>0)f[x]+=ans;
    
                }else{
                    read(x);
                    ll ans=all-f[x]-tim*dep[x];
                    ans+=st.tquery(1,x);
    //                printf("(%lld)",st.tquery(1,x));
                    printf("%lld
    ",ans);
                }
            }
        }
    }
    
  • 相关阅读:
    宏观经济指标
    Poloniex API 文档
    雪球释老毛推荐的投资者书单
    数字货币开源项目——貔貅
    数字货币量化分析报告_20170905_P
    数字货币量化分析报告_2017-09-05
    数字货币量化分析报告_2017-09-04
    ICO成本价
    Python3使用Print输出带颜色字体
    Ta-lib函数功能列表
  • 原文地址:https://www.cnblogs.com/kkkek/p/13455458.html
Copyright © 2011-2022 走看看