HDU 6161 Big binary tree

来源:互联网 发布:y系列电动机的技术数据 编辑:程序博客网 时间:2024/06/04 23:19

这里写图片描述
学了波标程。
每次修改从下往上更新dp值,dp值用贪心维护:如果左右儿子有被修改过,则返回其dp值,否则往下log(n)走到底,尽量选择靠右的点。
每次查询从下往上更新答案就可以枚举所有情况了。

代码:

#include<bits/stdc++.h>using namespace std;#define lc(X) (X<<1)#define rc(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, cl = 0, cr = 0;    while(lc(t) <= n) cl++, t = lc(t);    t = x;    while(rc(t) <= n) cr++, t = rc(t);    if(cl != cr) t = n;    LL ret = 0;    while(t >= x) ret += t, t >>= 1;    return ret;}void modify(int x, int y) {    val[x] = y;    while(x) {        f[x] = max(cal(lc(x)), cal(rc(x)))+(val.count(x)?val[x]:x);        x >>= 1;    }}LL query(int x) {    LL ret = cal(lc(x))+cal(rc(x))+(val.count(x)?val[x]:x);    LL dist = cal(x);    while((x>>1) > 0) {        bool flag = (x&1)?1:0;        x >>= 1;        dist += val.count(x)?val[x]:x;        if(flag) ret = max(ret, cal(lc(x))+dist);        else ret = max(ret, cal(rc(x))+dist);    }    return ret;}int main() {    char s[10];    int m, x, y;    while(~scanf("%d%d", &n, &m)) {        val.clear(), f.clear();        while(m--) {            scanf("%s%d", s, &x);            if(s[0] == 'q') printf("%lld\n", query(x));            else scanf("%d", &y), modify(x, y);        }    }    return 0;}
原创粉丝点击