HDU 5692 Snacks (百度之星2A)

分析:

題意就是根節點到i 子樹上所有點的最大值,並且這棵樹上的點權可修改。
那麼維護所有點到根的和,如果修改一個u 節點,只會改變根到u 子樹上點的和。把樹用dfs 序遍歷一下,把樹變成一個序列,修改節點就變成了序列的區間修改,找最大值也變成了區間找最值。一棵線段樹搞定了。
複雜度:o(mlogn)

代碼:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <string>

using namespace std;

typedef long long LL;
typedef vector <int>    VI;
typedef pair <int,int>  PII;
#define FOR(i,x,y)  for(int i = x;i < y;++ i)
#define IFOR(i,x,y) for(int i = x;i > y;-- i)
#define pb  push_back
#define mp  make_pair
#define fi  first
#define se  second
#define lrt rt<<1
#define rrt rt<<1|1
#define lson    rt<<1,l,mid
#define rson    rt<<1|1,mid+1,r

const int maxn = 200010;
VI  mat[maxn];
LL a[maxn],suf[maxn],w[maxn];
int n,m;

int tot,dfn[maxn],s[maxn],t[maxn];

void dfs(int u,int fa){
    if(fa == -1)    suf[u] = a[u];
    else    suf[u] = a[u]+suf[fa];
    dfn[++tot] = u; s[u] = tot; w[tot] = suf[u];
    FOR(i,0,(int)mat[u].size()){
        int v = mat[u][i];
        if(v == fa) continue;
        dfs(v,u);
    }
    dfn[++tot] = u; t[u] = tot; w[tot] = suf[u];
}

struct Tree{
    int l,r;
    LL val,lazy;
}tree[maxn<<2];

void pushup(int rt){
    tree[rt].val = max(tree[lrt].val,tree[rrt].val);
}

void pushdown(int rt){
    if(tree[rt].lazy){
        tree[lrt].val += tree[rt].lazy;
        tree[rrt].val += tree[rt].lazy;
        tree[lrt].lazy += tree[rt].lazy;
        tree[rrt].lazy += tree[rt].lazy;
        tree[rt].lazy = 0;
    }
}

void build(int rt,int l,int r){
    tree[rt].l = l; tree[rt].r = r;
    tree[rt].lazy = 0;
    if(l == r){
        tree[rt].val = w[l];
        return;
    }
    int mid = (l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt);
}

void modify(int rt,int l,int r,int lazy){
    if(tree[rt].l == l && tree[rt].r == r){
        tree[rt].val += lazy;
        tree[rt].lazy += lazy;
        return;
    }
    pushdown(rt);
    int mid = (tree[rt].l+tree[rt].r)>>1;
    if(r <= mid)    modify(lrt,l,r,lazy);
    else if(l > mid)    modify(rrt,l,r,lazy);
    else{
        modify(lson,lazy);
        modify(rson,lazy);
    }
    pushup(rt);
}

LL query(int rt,int l,int r){
    if(l == tree[rt].l && r == tree[rt].r)  return tree[rt].val;
    pushdown(rt);
    int mid = (tree[rt].l+tree[rt].r)>>1;
    if(r <= mid)    return query(lrt,l,r);
    else    if(l > mid) return query(rrt,l,r);
    else    return max(query(lson),query(rson));
}

void work(){
    tot = 0;    dfs(0,-1);
    build(1,1,tot);
    FOR(i,0,m){
        int cmd,x,y;
        scanf("%d",&cmd);
        if(cmd){
            scanf("%d",&x);
            printf("%I64d\n",query(1,s[x],t[x]));
        }
        else{
            scanf("%d%d",&x,&y);
            modify(1,s[x],t[x],y-a[x]);
            a[x] = y;
        }
    }
}

int main(){
    int T,tCase = 0;    scanf("%d",&T);
    while(T--){
        printf("Case #%d:\n",++tCase);
        scanf("%d%d",&n,&m);
        FOR(i,0,maxn)   mat[i].clear();
        int u,v;
        FOR(i,1,n)  scanf("%d%d",&u,&v),mat[u].pb(v),mat[v].pb(u);
        FOR(i,0,n)  scanf("%I64d",&a[i]);
        work();
    }
    return 0;
}
發佈了157 篇原創文章 · 獲贊 13 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章