zoukankan      html  css  js  c++  java
  • HDU 5692 Snacks(DFS序+线段树)

    Snacks

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 3213    Accepted Submission(s): 743

    Problem Description
    百度科技园内有n个零食机,零食机之间通过n1条路相互连通。每个零食机都有一个值v,表示为小度熊提供零食的价值。
    由于零食被频繁的消耗和补充,零食机的价值v会时常发生变化。小度熊只能从编号为0的零食机出发,并且每个零食机至多经过一次。另外,小度熊会对某个零食机的零食有所偏爱,要求路线上必须有那个零食机。
    为小度熊规划一个路线,使得路线上的价值总和最大。

    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
    Source
    中文题  题意不解释
    修改每个节点的权值  改变的是这个点的子树中的点到根节点的价值和
    求根节点路过这个点的路径的最大和  就是求根节点到这个点已经这个点的子树中的那个最大价值和
    我们就可以用DFS序 得到每个点的时间戳  将这个时间戳转化为线段树 修改一个点的权值 就相当他区间修改 修改这个区间的权值
    查询也就是查询区间的最大值
     
      1 #pragma comment(linker, "/STACK:1024000000,1024000000")
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<string.h>
      8 #include<set>
      9 #include<vector>
     10 #include<queue>
     11 #include<stack>
     12 #include<map>
     13 #include<cmath>
     14 typedef long long ll;
     15 typedef unsigned long long LL;
     16 using namespace std;
     17 const double PI=acos(-1.0);
     18 const double eps=0.0000000001;
     19 const int INF=1e9;
     20 const int N=500000+100;
     21 int head[N];
     22 int tot;
     23 ll a[N];
     24 ll b[N];
     25 int n,m;
     26 struct NOde{
     27     int l,r;
     28     ll val;
     29     ll lazy;
     30 }tree[N*4];
     31 struct node{
     32     int to,next;
     33 }edge[N<<1];
     34 int L[N],R[N];
     35 int time;
     36 ll dis[N];
     37 void init(){
     38     memset(head,-1,sizeof(head));
     39     tot=0;
     40     time=0;
     41 }
     42 void add(int u,int v){
     43     edge[tot].to=v;
     44     edge[tot].next=head[u];
     45     head[u]=tot++;
     46 }
     47 void DFS(int x,int fa){
     48     L[x]=++time;
     49     b[time]=x;
     50     for(int i=head[x];i!=-1;i=edge[i].next){
     51         int v=edge[i].to;
     52         if(v==fa)continue;
     53         a[v]=a[x]+a[v];
     54         DFS(v,x);
     55     }
     56     R[x]=time;
     57 }
     58 void pushdown(int pos){
     59     if(tree[pos].lazy){
     60         tree[pos<<1].val+=tree[pos].lazy;
     61         tree[pos<<1|1].val+=tree[pos].lazy;
     62         tree[pos<<1].lazy+=tree[pos].lazy;
     63         tree[pos<<1|1].lazy+=tree[pos].lazy;
     64         tree[pos].lazy=0;
     65 
     66     }
     67 }
     68 void build(int left,int right,int pos){
     69    // cout<<55<<endl;
     70     tree[pos].l=left;
     71     tree[pos].r=right;
     72     tree[pos].lazy=0;
     73     int mid=tree[pos].l+tree[pos].r>>1;
     74     if(tree[pos].l==tree[pos].r){
     75         tree[pos].val=a[b[left]];
     76         return ;
     77     }
     78     build(left,mid,pos<<1);
     79     build(mid+1,right,pos<<1|1);
     80     tree[pos].val=max(tree[pos<<1].val,tree[pos<<1|1].val);
     81 
     82 }
     83 void update(int left,int right,int pos,ll x){
     84     if(tree[pos].l==left&&tree[pos].r==right){
     85         tree[pos].lazy+=x;
     86         tree[pos].val+=x;
     87         return ;
     88     }
     89     pushdown(pos);
     90     int mid=(tree[pos].l+tree[pos].r)>>1;
     91     if(mid>=right)update(left,right,pos<<1,x);
     92     else if(mid<left)update(left,right,pos<<1|1,x);
     93     else{
     94         update(left,mid,pos<<1,x);
     95         update(mid+1,right,pos<<1|1,x);
     96     }
     97     tree[pos].val=max(tree[pos<<1].val,tree[pos<<1|1].val);
     98 }
     99 ll query(int left,int right,int pos){
    100     if(tree[pos].l==left&&tree[pos].r==right){
    101         return tree[pos].val;
    102     }
    103     pushdown(pos);
    104     int mid=(tree[pos].l+tree[pos].r)>>1;
    105     if(mid>=right){
    106         return query(left,right,pos<<1);
    107     }
    108     else if(left>mid){
    109         return query(left,right,pos<<1|1);
    110     }
    111     else{
    112         return max(query(left,mid,pos<<1),query(mid+1,right,pos<<1|1));
    113     }
    114 }
    115 int main(){
    116     int t;
    117     scanf("%d",&t);
    118     int Case=1;
    119     while(t--){
    120         init();
    121         scanf("%d%d",&n,&m);
    122         int u,v;
    123         for(int i=1;i<n;i++){
    124             scanf("%d%d",&u,&v);
    125             add(u,v);
    126             add(v,u);
    127         }
    128         for(int i=0;i<n;i++){
    129             scanf("%I64d",&a[i]);
    130             dis[i]=a[i];
    131         }
    132         DFS(0,-1);
    133         build(1,time,1);
    134         int flag;
    135         int x;
    136         ll y;
    137         printf("Case #%d:
    ",Case++);
    138         while(m--){
    139             scanf("%d",&flag);
    140             if(flag==0){
    141                 scanf("%d%I64d",&x,&y);
    142                 update(L[x],R[x],1,(ll)y-dis[x]);
    143                 dis[x]=y;
    144             }
    145             else{
    146                 scanf("%d",&x);
    147                 ll ans=query(L[x],R[x],1);
    148                 printf("%I64d
    ",ans);
    149             }
    150 
    151         }
    152 
    153     }
    154 }
  • 相关阅读:
    windows和linux下安装 redis
    YII1 配置redis并使用
    YII1 安装smarty模版引擎
    thinkphp5 阿里云短信 发送多参数的短信
    利用securecrt或者xshell 下载服务器端文件到本地windows系统中
    Swift 内存管理
    扩展和协议
    继承
    构造与析构
    方法
  • 原文地址:https://www.cnblogs.com/Aa1039510121/p/7336910.html
Copyright © 2011-2022 走看看