HDU5692 Snacks DFS+线段树

分析:一棵以1为根的有根树,然后每个点维护从根到当前节点的路径和,当修改一个点时

只会影响的子树的和,最优值也是子树最大的值

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int N=1e5+5;
const LL INF=1ll*1e11;
struct Edge{
  int v,next;
}edge[N<<1];
int head[N],tot;
void add(int u,int v){
  edge[tot].v=v;
  edge[tot].next=head[u];
  head[u]=tot++;
}
int s[N],t[N],clk,match[N],n,m,a[N];
LL sum[N],c[N<<2],lz[N<<2];
void dfs(int u,int f){
  s[u]=++clk;match[s[u]]=u;
  sum[u]+=sum[f];
  for(int i=head[u];~i;i=edge[i].next){
     int v=edge[i].v;
     if(v==f)continue;
     dfs(v,u);
  }
  t[u]=clk;
}
void up(int rt){
   c[rt]=max(c[rt<<1],c[rt<<1|1]);
}
void down(int rt){
   if(lz[rt]){
      c[rt<<1]+=lz[rt];
      c[rt<<1|1]+=lz[rt];
      lz[rt<<1]+=lz[rt];
      lz[rt<<1|1]+=lz[rt];
      lz[rt]=0;
   }
}
void build(int rt,int l,int r){
   lz[rt]=0;  
   if(l==r){c[rt]=sum[match[l]];return;}
   int m=(l+r)>>1;
   build(rt<<1,l,m);
   build(rt<<1|1,m+1,r);
   up(rt);
}
int tmp;
void modify(int rt,int l,int r,int x,int y){
  if(x<=l&&r<=y){
    lz[rt]+=1ll*tmp;
    c[rt]+=1ll*tmp;
    return;
  }
  int m=(l+r)>>1;
  down(rt);
  if(x<=m)modify(rt<<1,l,m,x,y);
  if(y>m)modify(rt<<1|1,m+1,r,x,y);
  up(rt);
}
LL ask(int rt,int l,int r,int x,int y){
  if(x<=l&&r<=y)return c[rt];
  LL ans=-INF;
  int m=(l+r)>>1;
  down(rt);
  if(x<=m)ans=max(ans,ask(rt<<1,l,m,x,y));
  if(y>m)ans=max(ans,ask(rt<<1|1,m+1,r,x,y));
  return ans;
}
int main()
{
    int T,cas=0;
    scanf("%d",&T);
    while(T--){
      printf("Case #%d:\n",++cas);
      scanf("%d%d",&n,&m);
      for(int i=1;i<=n;++i)head[i]=-1;
        clk=tot=0;
      for(int i=1;i<n;++i){
        int u,v;
        scanf("%d%d",&u,&v);
        ++u,++v;
        add(u,v),add(v,u);
      }
      for(int i=1;i<=n;++i)
        scanf("%I64d",&sum[i]),a[i]=(int)sum[i];
      dfs(1,0);
      build(1,1,n);
      for(int i=0;i<m;++i){
        int op,x,y;
        scanf("%d%d",&op,&x);
        ++x;
        if(!op){
          scanf("%d",&y);
          tmp=y-a[x];
          a[x]=y;
          if(tmp)modify(1,1,n,s[x],t[x]);
        }
        else{
          printf("%I64d\n",ask(1,1,n,s[x],t[x]));
        }
      }
    }
    return 0;
}
View Code

 

posted @ 2016-05-24 22:39  shuguangzw  阅读(167)  评论(0编辑  收藏  举报