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;
}

时间: 2024-10-12 18:08:26

HDU5692 Snacks DFS+线段树的相关文章

2014 Super Training #9 F A Simple Tree Problem --DFS+线段树

原题: ZOJ 3686 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3686 这题本来是一个比较水的线段树,结果一个mark坑了我好几个小时..哎.太弱. 先DFS这棵树,树形结构转换为线性结构,每个节点有一个第一次遍历的时间和最后一次遍历的时间,之间的时间戳都为子树的时间戳,用线段树更新这段区间即可实现更新子树的效果,用到懒操作节省时间. 坑我的地方: update时,不能写成:tree[rt].mark = 1,

HDU 5877 dfs+ 线段树(或+树状树组)

1.HDU 5877  Weak Pair 2.总结:有多种做法,这里写了dfs+线段树(或+树状树组),还可用主席树或平衡树,但还不会这两个 3.思路:利用dfs遍历子节点,同时对于每个子节点au,查询它有多少个祖先av满足av<=k/au. (1)dfs+线段树 #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm>

POJ 3321 Apple Tree (dfs+线段树)

题目大意: 修改树上的节点,然后求子树的和. 思路分析: dfs 重新编号,烂大街了... #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define maxn 100005 #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e using namespace std

CodeForces - 383C Propagating tree(dfs + 线段树)

题目大意: 给出一棵树,树上每个节点都有权值,然后有两个操作. 1 x val 在结点x上加上一个值val,x的儿子加上 -val,x的儿子的儿子加上 - (-val),以此类推. 2 x 问x节点的值. 思路分析: 每个节点上加值都是给自己的儿子节点加,而且这个是颗树. 比如样例上的,如果你给node 1加一个值,那么五个节点都加. 再给node 2加个值,2的儿子节点也加了,之前给1加的值也要加到2号节点的儿子. 所以你会发现节点的儿子会存在一个从属的关系. 这样的话,我们可以把所有节点从新

dfs+线段树 zhrt的数据结构课

zhrt的数据结构课 这个题目我觉得是一个有一点点思维的dfs+线段树 虽然说看起来可以用树链剖分写,但是这个题目时间卡了树剖 因为之前用树剖一直在写这个,所以一直想的是区间更新,想dfs+线段树,有点点没想明白 后来才知道可以把这个区间更新转化成单点更新,就是查一个结点的子树,如果子树有可以到根节点的,那么这个结点肯定也可以到根节点. #include <cstdio> #include <cstring> #include <algorithm> #include

HDU5692 Snacks DFS序 线段树

题目 HDU5692 Snacks Problem Description 百度科技园内有n个零食机,零食机之间通过n?1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化.小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次.另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机. 为小度熊规划一个路线,使得路线上的价值总和最大. Input 输入数据第一行是一个整数T(T≤10),表示有T组测试数

hdu-5692 Snacks(dfs序+线段树)

题目链接: Snacks Problem Description 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化.小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次.另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机. 为小度熊规划一个路线,使得路线上的价值总和最大. Input 输入数据第一行是一个整数T(T≤10),表示有TT组测试数据. 对

【Codeforces-707D】Persistent Bookcase DFS + 线段树

D. Persistent Bookcase Recently in school Alina has learned what are the persistent data structures: they are data structures that always preserves the previous version of itself and access to it when it is modified. After reaching home Alina decided

hdu-2586 How far away ?(lca+bfs+dfs+线段树)

题目链接: How far away ? Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Others) Problem Description There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this