• HDU 6161 Big binary tree


    题目:http://acm.hdu.edu.cn/showproblem.php?pid=6161

    题意:给你一颗二叉树,每个节点的值为自身,接下来有2种操作

    query:查询经过该点的路径的最大值

    change:将一个点的值改变
     
    官方题解:
    考虑dp,f(x)表示从点x开始向下走得到的最大的点权和,查询直接从x开始向上走更新答案即可。
    考虑快速算 f(x) 对于子树内没有被修改过的点的 f(x) 可以快速分类讨论算出,而不满足本条件的点只有 O(mlogm) 个,在hash上dp即可。
     
    f(x)用贪心进行计算,先看左右儿子的深度,如果相同则选择右儿子走到底,否则最后应该选择n为最后的节点
    查询时需要枚举所有情况
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    using namespace std;
    #define l(X) (X<<1)
    #define r(X) (X<<1|1)
    typedef long long ll;
    int n;
    map<int,ll>f,val;
    
    ll cal(int x)
    {
        if (x>n) return 0;
        if (f.count(x)) return f[x];
        int t=x,sl=0,sr=0;
        while(l(t)<=n)
        {
            sl++;
            t=l(t);
        }
        t=x;
        while(r(t)<=n)
        {
            sr++;
            t=r(t);
        }
        if (sl!=sr) t=n;
        ll ans=0;
        while(t>=x)
        {
            ans+=t;
            t>>=1;
        }
        return ans;
    }
    void update(int x,int y)
    {
        val[x]=y;
        while(x)
        {
            f[x]=max(cal(l(x)),cal(r(x))) +(val.count(x)?val[x]:x);
            x>>=1;
        }
    }
    ll query(int x)
    {
        ll ans=cal(l(x))+cal(r(x))+(val.count(x)?val[x]:x);
        ll now=cal(x);
        while(x>>1)
        {
            bool flag=x&1;
            x>>=1;
            now+=(val.count(x)?val[x]:x);
            if (flag) ans=max(ans,now+cal(l(x)));
            else ans=max(ans,now+cal(r(x)));
        }
        return ans;
    }
    int main()
    {
        char s[10];
        int m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            f.clear();val.clear();
            int x,y;
            while(m--)
            {
                scanf("%s",s);
                if (s[0]=='q')
                {
                    scanf("%d",&x);
                    printf("%lld
    ",query(x));
                }
                else
                {
                    scanf("%d%d",&x,&y);
                    update(x,y);
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    调用同一个类的另一个方法,导致该方法的事物失效问题。。做记录
    JS点名功能
    JS复制功能
    js局部刷新
    基于 Token 的身份验证方法
    JS获取URL“#”后的值
    JS批量打包下载图片(笔记)
    九阴真经
    弹框播放腾讯视频(Iframe)
    js sessionStorage会话存取/删除
  • 原文地址:https://www.cnblogs.com/bk-201/p/7419155.html
Copyright © 2020-2023  润新知