HDU 6161 (2017多校9

来源:互联网 发布:最近比较火的网络歌曲 编辑:程序博客网 时间:2024/05/16 10:23

题意:

给你一个n (n <= 1e8)个节点的完全二叉树, 开始时,每个节点的权值 为他本身, 两种操作:

1. 查询经过节点x 的最大权值链。

2. 改变x 的权值为v


思路:

n是1e8,没法建树。

但他是一个完全二叉树,一条链就log n 个点。

那么我们每次修改权值时 , 维护一下这条链的信息。 那么我们只需要n log n 的空间就足够了。


所有 我们令dp[x]表示 从x 往下走 最大权值是多少。

val[x]表示 x 这个点权值是多少,如果没有, 表示为本身(初始状态)

然后就是模拟就行了。


#include <cstdio>#include <cstring>#include <algorithm>#include <map>using namespace std;map<int, long long >dp, val;char s[10];int n, q;long long calc(int x){    if (x > n) return 0;    if (dp.count(x)) return dp[x];    int d1 = 0;    int d2 = 0;    int x2 = x;    while(x2 <= n){        ++d1;        x2 = x2 * 2 + 1;    }    int x3 = x;    while(x3 <= n){        ++d2;        x3 = x3 * 2;    }    long long sum = 0;    if (x2 > n){        x2 >>= 1;    }    while(x2 != x){        sum += x2;        x2 /= 2;    }    sum += x2;    long long ans = sum;    sum = 0;    if (d1 != d2){        x2 = n;        while(x2 != x){            sum += x2;            x2 /= 2;        }        sum += x2;        ans = max(ans, sum);    }    return ans;}void change(int x,long long v){    val[x] = v;    dp[x] = max(calc(x<<1), calc(x << 1 | 1)) + v;    int md = x % 2;    long long ans = max(calc(x<<1) , calc(x << 1 | 1)) + v;    x/= 2;    while(x > 1){        long long t;        if (val.count(x)) t = val[x];        else t = x;//        ans += t;        if (md){            dp[x] = max(calc(x << 1), ans) + t;        }        else {            dp[x] = max(ans, calc(x<<1|1) ) + t;        }        ans = dp[x];        md = x % 2;        x /= 2;    }}long long query(int x){    long long t;    if (val.count(x)) t = val[x];    else t = x;    long long ans = calc(x << 1) + calc(x << 1 | 1) + t;    long long tmp = calc(x);    int md = x % 2;    x >>= 1;    while(x >= 1){        if (val.count(x))t = val[x];        else t = x;        tmp += t;        if (md){            ans = max(ans, calc(x << 1) + tmp);        }        else {            ans = max(ans, calc(x<<1|1) + tmp);        }        md = x % 2;        x /= 2;    }    return ans;}int main(){    while(~scanf("%d %d",&n, &q)){        val.clear();        dp.clear();        for (int i = 0; i < q; ++i){            scanf("%s", s);            if (s[0] == 'q'){                int x;                scanf("%d",&x);                long long ans = query(x);                printf("%I64d\n", ans);            }            else {                int x;                long long v;                scanf("%d%I64d", &x, &v);                change(x, v);            }        }    }    return 0;}

Big binary tree

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 492    Accepted Submission(s): 168


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 13query 1query 2query 3query 4query 5query 6change 6 1query 1query 2query 3query 4query 5query 6
 

Sample Output
171717161717121212111212
 

Source
2017 Multi-University Training Contest - Team 9
 

Recommend
liuyiding   |   We have carefully selected several similar problems for you:  6181 6180 6179 6178 6177 
 

Statistic | Submit | Discuss | Note

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 身份证过期了怎么办护照 驾照体检表丢了怎么办 驾照体检表掉了怎么办 驾校体检表掉了怎么办 身份证掉了怎么办护照 驾照体检表过期了怎么办 助力车行驶证过期怎么办 c1证骑摩托车怎么办 别人知道驾驶证号码怎么办 摩托车卖了车牌怎么办 违章超过12分怎么办 违章扣分24分怎么办 驾驶证有效期过了怎么办 驾驶证到期没审怎么办 驾驶证扣不了分怎么办 集体户口怎么办户口本公证 强制保险单丢了怎么办 车子保险单丢了怎么办 汽车保险单子丢了怎么办 汽车保险贴丢了怎么办 保险本子丢了怎么办 平安保险单丢了怎么办 人寿保险单丢了怎么办 个人保险单丢了怎么办 学生保险单丢了怎么办 车保险单丢了怎么办 小孩保险单丢了怎么办 江苏省河道疏浚证怎么办 友利银行怎么办卡 专票信息没固话怎么办 廊坊市交警队放车后乱收费怎么办 驾驶本到期了怎么办 出国读研档案怎么办 出国留学 报到证怎么办 驾驶证扣分超证怎么办 车子违章132分怎么办 人才档案丢了怎么办 营运证过期三年怎么办 营运证年审过期怎么办 动态磅显示超载怎么办 货车道路运输证怎么办