HDU 5692 Snacks (百度之星2A)

来源:互联网 发布:y系列电机下线数据大全 编辑:程序博客网 时间:2024/04/29 08:29

分析:

题意就是根节点到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,rconst 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;}
0 0
原创粉丝点击