题目链接

Problem Description

You are given a complete binary tree with n nodes. The root node is numbered 1, and node x's father node is ⌊x/2⌋. At the beginning, node x has a value of exactly x. We define the value of a path as the sum of all nodes it passes(including two ends, or one if the path only has one node). Now there are two kinds of operations:
1.  change u x Set node u's value as x(1≤u≤n;1≤x≤10^10)
2.  query u Query the max value of all paths which passes node u.
 
Input
There are multiple cases.
For each case:
The first line contains two integers n,m(1≤n≤10^8,1≤m≤10^5), which represent the size of the tree and the number of operations, respectively.
Then m lines follows. Each line is an operation with syntax described above.
 
Output
For each query operation, output an integer in one line, indicating the max value of all paths which passes the specific node.
 
Sample Input
6 13
query 1
query 2
query 3
query 4
query 5
query 6
change 6 1
query 1
query 2
query 3
query 4
query 5
query 6
 
Sample Output
17
17
17
16
17
17
12
12
12
11
12
12
 
题意:有一棵 由 n 个节点构成的完全二叉树,节点编号1~n,对于i节点其父亲节点为i/2,并且其初始权值为 x ,现在有m次操作:1、修改节点 i 权值为 x 。   2、求经过i节点的所有路径中路径上节点最大权值和。
 
思路:由于n很大1e8,所以不能直接建树进行计算,不能建树怎么计算呢?发现询问的m为1e5 ,所以我们可以用map保存修改的节点。对于每次修改一个节点u时,我们可以计算并用map存下u的子树中从u到其叶子节点的最大权值和,并且向上搜索u的祖先节点,也用map存下相应的最大路径权值和。 对于询问经过 u 的最大的路径权值和,我们只需要从u向上搜索祖先节点即可。
        如求经过D的最大路径权值和。有以下的路径:1、起始为从D的叶子节点经D到D的另一个叶子节点。 2、从D的叶子节点经D B 到B的一个叶子节点。  3、从D的一个叶子节点经B D A 到A的一个叶子节点。所以求经过D的最大路径权值和时就是由D开始向上搜索D的祖先节点,进行计算。
 
代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
using namespace std;
typedef long long LL;
map<int,LL>mp;
map<int,LL>mx;
LL ans;
int n,m;
int pos[]; void init()
{
int tmp=n;
int deep=(int)log2(n)+;
for(int i=deep;i>=;i--)
{
pos[i]=tmp;
tmp>>=;
}
} void cal(int x)
{
if(mp.count(x)) return ;
if(x>n) { mp[x]=; return ; }
int deep=(int)log2(x)+;
LL tmp=;
for(int i=x;i<=n;i=(i<<|)) tmp+=i;
if(pos[deep]==x){
LL sum=;
for(int i=deep;;i++)
{
sum+=pos[i];
if(pos[i]==n) break;
}
tmp=max(tmp,sum);
}
mp[x]=tmp;
} void update(int x)
{
if(!x) return ;
LL y;
if(mx.count(x)==) y=x;
else y=mx[x];
cal(x<<);
cal(x<<|);
mp[x]=max(mp[x<<],mp[x<<|])+y;
update(x>>);
} void query(LL sum,int x,int son)
{
if(!x) return ;
cal(x<<);
cal(x<<|);
if(!mx.count(x)) mx[x]=x;
ans=max(ans,sum+mp[son^]+mx[x]);
sum+=mx[x];
query(sum,x>>,x);
} int main()
{
char s[];
while(scanf("%d",&n)!=EOF)
{
init();
mp.clear();
mx.clear();
scanf("%d",&m);
while(m--)
{
scanf("%s",s);
if(s[]=='q')
{
int x; scanf("%d",&x);
cal(x<<);
cal(x<<|);
if(!mx.count(x)) mx[x]=x;
ans=mp[x<<]+mp[x<<|]+mx[x];
cal(x);
query(mp[x],x>>,x);
printf("%lld\n",ans);
}
else
{
int x; LL y; scanf("%d%lld",&x,&y);
mx[x]=y;
update(x);
}
}
}
return ;
}

hdu 6161--Big binary tree(思维--压缩空间)的更多相关文章

  1. 2017多校第9场 HDU 6161 Big binary tree 思维,类似字典树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6161 题意: 题目是给一棵完全二叉树,从上到下从左到右给每个节点标号,每个点有权值,初始权值为其标号, ...

  2. 2017 Multi-University Training Contest - Team 9 1001&&HDU 6161 Big binary tree【树形dp+hash】

    Big binary tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  3. HDU 6161.Big binary tree 二叉树

    Big binary tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  4. 【hdu 6161】Big binary tree(二叉树、dp)

    多校9 1001 hdu 6161 Big binary tree 题意 有一个完全二叉树.编号i的点值是i,操作1是修改一个点的值为x,操作2是查询经过点u的所有路径的路径和最大值.10^5个点,1 ...

  5. Binary Tree HDU - 5573 (思维)

    题目链接: B - Binary Tree  HDU - 5573 题目大意: 给定一颗二叉树,根结点权值为1,左孩子权值是父节点的两倍,右孩子是两倍+1: 给定 n 和 k,让你找一条从根结点走到第 ...

  6. HDU 1710 二叉树的遍历 Binary Tree Traversals

    Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  7. HDU 5573 Binary Tree 构造

    Binary Tree 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5573 Description The Old Frog King lives ...

  8. HDU 1710 Binary Tree Traversals (二叉树遍历)

    Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  9. HDU 1710 Binary Tree Traversals(树的建立,前序中序后序)

    Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

随机推荐

  1. Selenium WebDriver 对Cookie进行处理绕过登录验证码

    首先需要手动登录一次你的测试网站,去Chrome的F12中获取这个网站的cookie信息,找到对应的保存登录信息的cookie,接下来在代码中将上述的cookie信息通过webdriver写入的自动化 ...

  2. NodeJs学习相关网址

    node官方中文 https://nodejs.org/zh-cn/   Node.js 中文网 https://nodejs.org/zh-cn/   Node.js 教程 | 菜鸟教程 http: ...

  3. java集合: jdk1.8的hashMap原理简单理解

    HashMap的数据结构 HashMap是数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,他的底层结构是一个数组,而数组的元素是一个单向链表.HashMap默认初始化的是一个长度为16位的数 ...

  4. 微信小程序记账本进度二

    二.1,下载微信web开发者工具 2,使用新注册的账号登录,并创建工程

  5. 【mac上安装&配置&使用git】

    转自:https://www.jianshu.com/p/7edb6b838a2e 目录 安装git 创建ssh key.配置git 提交本地项目到GitHub 一.安装Git MAC 上安装Git主 ...

  6. jq怎么给图片绑定上传文件按钮

    html代码 <img src="/img/zhengmian.png" alt="" class="file1"> <i ...

  7. 【PHP面试题】通俗易懂的两个面试必问的排序算法讲解:冒泡排序和快速排序

    又到了金三银四找工作的时间,相信很多开发者都在找工作或者准备着找工作了.一般应对面试,我们无可厚非的去刷下面试题.对于PHPer来说,除了要熟悉自己所做的项目,还有懂的基本的算法.下面来分享下PHP面 ...

  8. PHP开发——超全局数组变量

    概述 l  JS中的变量分两类:局部变量.全局变量. l  PHP中的变量分三类:局部变量.全局变量.超全局变量. l  局部变量:在函数内部声明的变量,就是局部变量.函数执行完毕,局部变量就消失了. ...

  9. 201621123002《JAVA程序设计》第三章学习总结

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词,如类.对象.封装等 关键词:类 对象 封装 构造函数 this,static,final 1.2 用思维导图或者Onenote或 ...

  10. Linux 只列出目录的方法

    1. ls -d 2. find -type d -maxdepth 1 3. ls -F | grep "/$" 4. ls -l | grep "^d"