zoukankan      html  css  js  c++  java
  • Codeforces Round #362 (Div. 2) C

    C. Lorenzo Von Matterhorn

    题意:一初始无权的二叉树(第i歌节点有2条边 i-2i  i-2i+1),节点个数最多10^18  给出2个操作1 u v w 表示给 u->v 路径上的每一条边加上w的权值 2 u v 表示询问u->v的路径的权值和

    思路:给每个节点设置2个点权 左孩子点权l 和右孩子点权r 每次操作沿路径修改点权 或累加权值和

    AC代码:

    #include"stdio.h"
    #include"math.h"
    #include"map"
    #include"string.h"
    #include"iostream"
    #include"algorithm"
    #define ll long long
    using namespace std;
    struct Node{
        ll l,r;
        Node(){
            l=0,r=0;
        }
    };
    map<ll,Node> M;
    int getcc(ll x){
        int ans=0;
        while(x){
            x>>=1;
            ans++;
        }
        return ans;
    }
    int main(){
        ll q,f,u,v,w;
        cin>>q;
        for(int k=0; k<q; ++k){
            scanf("%lld",&f);
            if(f==1){
                scanf("%lld%lld%lld",&u,&v,&w);
                int gu=getcc(u), gv=getcc(v);
                if(gu<gv){
                    swap(u,v);
                    swap(gu,gv);
                }
                while(gu>gv){
                    if(u&1) M[u].r+=w;
                    else M[u].l+=w;
                    u>>=1;
                    gu--;
                }
                while(u!=v){
                    if(u&1) M[u].r+=w;
                    else M[u].l+=w;
                    u>>=1;
                    if(v&1) M[v].r+=w;
                    else M[v].l+=w;
                    v>>=1;
                }
            }
            else{
                scanf("%lld%lld",&u,&v);
                ll ans=0;
                int gu=getcc(u),gv=getcc(v);
                if(gu<gv){
                    swap(u,v);
                    swap(gu,gv);
                }
                while(gu>gv){
                    if(u&1) ans+=M[u].r;
                    else ans+=M[u].l;
                    u>>=1;
                    gu--;
                }
                while(u!=v){
                    if(u&1) ans+=M[u].r;
                    else ans+=M[u].l;
                    if(v&1) ans+=M[v].r;
                    else ans+=M[v].l;
                    u>>=1,v>>=1;
                }
                cout<<ans<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    Java 引用类型
    Mysql-5.7.14使用常见问题汇总
    CountBoard 是一个基于Tkinter简单的,开源的桌面日程倒计时应用
    HashMap的源码分析
    redis-cluster源码分析
    redis集群方案
    redis集群命令
    redis集群删除master节点
    redis集群添加master节点
    redis集群部署
  • 原文地址:https://www.cnblogs.com/max88888888/p/6684200.html
Copyright © 2011-2022 走看看