• 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:
    ",++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
    ",ask(1,1,n,s[x],t[x]));
            }
          }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    python并发编程之多进程(实践篇)
    python之网络编程
    python并发编程之协程(实践篇)
    python并发编程之IO模型(实践篇)
    复制命令(ROBOCOPY)
    创建文件命令
    创建文件夹命令
    复制命令(XCOPY)
    进程命令(tasklist)
    目录命令(tree)
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5525282.html
Copyright © 2020-2023  润新知