• 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;
    }
  • 相关阅读:
    推导式
    解构
    for 循环
    运算符
    while 循环
    流程控制语句
    索引和切片
    ASC转换BCD,ASC2BCD(转)
    CString和char互转,十六进制的BYTE转CString
    C++添加简单的日记记录
  • 原文地址:https://www.cnblogs.com/max88888888/p/6684200.html
Copyright © 2020-2023  润新知