zoukankan      html  css  js  c++  java
  • hdu-5692 Snacks(dfs序+线段树)

    题目链接:

    Snacks

    Problem Description
     

    百度科技园内有n个零食机,零食机之间通过n1条路相互连通。每个零食机都有一个值v,表示为小度熊提供零食的价值。

    由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化。小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次。另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机。

    为小度熊规划一个路线,使得路线上的价值总和最大。

     
    Input
     

    输入数据第一行是一个整数T(T10),表示有TT组测试数据。

    对于每组数据,包含两个整数n,m(1n,m100000),表示有n个零食机,m次操作。

    接下来n1行,每行两个整数xy(0x,y<n),表示编号为x的零食机与编号为y的零食机相连。

    接下来一行由n个数组成,表示从编号为0到编号为n-1的零食机的初始价值v(v<100000)。

    接下来m行,有两种操作:0 x y,表示编号为x的零食机的价值变为y1 x,表示询问从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。

    本题可能栈溢出,辛苦同学们提交语言选择c++,并在代码的第一行加上:

    #pragma comment(linker, "/STACK:1024000000,1024000000")

     
    Output
     

    对于每组数据,首先输出一行”Case #?:”,在问号处应填入当前数据的组数,组数从1开始计算。

    对于每次询问,输出从编号为0的零食机出发,必须经过编号为x零食机的路线中,价值总和的最大值。

     
    Sample Input
     
    1
    6 5
    0 1
    1 2
    0 3
    3 4
    5 3
    7 -5 100 20 -5 -7
    1 1
    1 3
    0 2 -1
    1 1
    1 5
    Sample Output
     
    Case #1:
    102
    27
    2
    20

    题意:


    思路:


    先把这棵树dfs求出距离并弄成线段树,l[x],r[x]分别表示x的子树节点的左右区间,每次修改[l[x],r[x]]这个区间,用线段树的区间修改,然后就好啦;


    AC代码:

    #include <bits/stdc++.h>
    /*
    #include <iostream>
    #include <queue>
    #include <cmath>
    #include <map>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    */
    using namespace std;
    #define Riep(n) for(int i=1;i<=n;i++)
    #define Riop(n) for(int i=0;i<n;i++)
    #define Rjep(n) for(int j=1;j<=n;j++)
    #define Rjop(n) for(int j=0;j<n;j++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
    typedef long long LL;
    const LL mod=1e9+7;
    const double PI=acos(-1.0);
    const LL inf=1e18;
    const int N=1e5+4;
    int n,m,head[N],l[2*N],r[2*N],cnt,num;
    LL dis[N],b[N],va[N];
    struct Edge
    {
        int to,next;
    }edge[2*N];
    void add_edge(int s,int e)
    {
        edge[cnt].next=head[s];
        edge[cnt].to=e;
        head[s]=cnt++;
    }
    void  dfs(int x,int fa)
    {
        num++;
        b[num]=dis[x];
        l[x]=num;
        for(int i=head[x];i!=-1;i=edge[i].next)
        {
            int y=edge[i].to;
            if(y!=fa)
            {
                dis[y]=dis[x]+va[y];
                dfs(y,x);
            }
        }
        r[x]=num;
    }
    struct Tree
    {
        int l,r;
        LL ans,lazy;
    }tr[4*N];
    void pushup(int o)
    {
        tr[o].ans=max(tr[2*o].ans,tr[2*o+1].ans);
    }
    void pushdown(int o)
    {
        if(tr[o].lazy)
        {
            tr[2*o].ans+=tr[o].lazy;
            tr[2*o+1].ans+=tr[o].lazy;
            tr[2*o].lazy+=tr[o].lazy;
            tr[2*o+1].lazy+=tr[o].lazy;
            tr[o].lazy=0;
        }
    }
    void build(int o,int L,int R)
    {
        tr[o].l=L;
        tr[o].r=R;
        tr[o].lazy=0;
        if(L>=R)
        {
            tr[o].ans=b[L];
            return ;
        }
        int mid=(L+R)>>1;
        build(2*o,L,mid);
        build(2*o+1,mid+1,R);
        pushup(o);
    }
    void update(int o,int L,int R,LL val)
    {
        if(L<=tr[o].l&&R>=tr[o].r)
        {
            tr[o].ans=tr[o].ans+val;
            tr[o].lazy=tr[o].lazy+val;
            return ;
        }
        int mid=(tr[o].l+tr[o].r)>>1;
        pushdown(o);
        if(R<=mid)update(2*o,L,R,val);
        else if(L>mid)update(2*o+1,L,R,val);
        else
        {
            update(2*o,L,mid,val);
            update(2*o+1,mid+1,R,val);
        }
        pushup(o);
    }
    LL query(int o,int L,int R)
    {
        if(L<=tr[o].l&&tr[o].r<=R)return tr[o].ans;
        int mid=(tr[o].l+tr[o].r)>>1;
        pushdown(o);
        if(R<=mid)return query(o*2,L,R);
        else if(L>mid)return query(o*2+1,L,R);
        else return max(query(2*o,L,mid),query(2*o+1,mid+1,R));
    }
    int main()
    {
          int t;
          scanf("%d",&t);
          int Case=1;
          while(t--)
          {
              printf("Case #%d:
    ",Case++);
              cnt=0;
              num=0;
              mst(head,-1);
              scanf("%d%d",&n,&m);
              int u,v;
              Riep(n-1)
              {
                  scanf("%d%d",&u,&v);
                  add_edge(u,v);
                  add_edge(v,u);
              }
              Riop(n)scanf("%I64d",&va[i]);
              dis[0]=va[0];
              dfs(0,-1);
              build(1,1,num);
              int flag,x,y;
              Riep(m)
              {
                  scanf("%d",&flag);
                  if(flag)
                  {
                      scanf("%d",&x);
                      printf("%I64d
    ",query(1,l[x],r[x]));
                  }
                  else
                  {
                      scanf("%d%d",&x,&y);
                      update(1,l[x],r[x],(LL)y-va[x]);
                      va[x]=(LL)y;
                  }
              }
          }
        return 0;
    }
  • 相关阅读:
    搭建单区域DNS服务器
    安装一个KVM服务器
    配置HTTPS网站服务器
    部署并测试动态WSGI站点
    java内置的四大函数式接口
    java自定义异常类
    java方法重写的规定
    spring跨重定向传递数据
    SpringEl表达式(转)
    Spring中的@conditional注解
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5534747.html
Copyright © 2011-2022 走看看