• 【DFS序+线段树区间更新区间求最值】HDU 5692 Snacks


    http://acm.hdu.edu.cn/showproblem.php?pid=5692

    【思路】

    • 每更新一个点,子树的所有结点都要更新,所以是区间更新
    • 每查询一个点,子树的所有结点都要查询,所以是区间查询最值
    • 线段树上结点的值是每个点到根这条链的权值和

    【AC】

      1 #pragma comment(linker, "/STACK:1024000000,1024000000")
      2 #include<bits/stdc++.h>
      3 #define lson l,mid,rt<<1
      4 #define rson mid+1,r,rt<<1|1 
      5 using namespace std;
      6 typedef long long ll;
      7 int n,m;
      8 const int maxn=1e5+2;
      9 const int maxm=2*maxn;
     10 const ll linf=1e18;
     11 struct edge
     12 {
     13     int to;
     14     int nxt;
     15 }e[maxm];
     16 int head[maxn];
     17 int tot;
     18 int cid;
     19 int st[maxn],ed[maxn];
     20 ll tree[maxn];
     21 ll a[maxn];
     22 ll lazy[maxn*4];
     23 ll sum[maxn*4];
     24 int que[maxn];
     25 void init()
     26 {
     27     memset(head,-1,sizeof(head));
     28     tot=0;
     29     cid=0;
     30     memset(tree,0,sizeof(tree));
     31     memset(lazy,0,sizeof(lazy));
     32 }
     33 void addedge(int u,int v)
     34 {
     35     e[tot].to=v;
     36     e[tot].nxt=head[u];
     37     head[u]=tot++;
     38 }
     39 void dfs(int u,int pa)
     40 {
     41     st[u]=++cid;
     42     que[cid]=u;
     43     for(int i=head[u];i!=-1;i=e[i].nxt)
     44     {
     45         int v=e[i].to;
     46         if(v==pa) continue;
     47         tree[v]=tree[u]+a[v];
     48         dfs(v,u);
     49     }
     50     ed[u]=cid;
     51 }
     52 void pushup(int rt)
     53 {
     54     sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
     55     return;
     56 }
     57 void pushdown(int rt)
     58 {
     59     if(lazy[rt])
     60     {
     61         sum[rt<<1]+=lazy[rt];
     62         sum[rt<<1|1]+=lazy[rt];
     63         lazy[rt<<1]+=lazy[rt];
     64         lazy[rt<<1|1]+=lazy[rt];
     65         lazy[rt]=0;    
     66     }
     67 }
     68 void build(int l,int r,int rt)
     69 {
     70     lazy[rt]=0;
     71     if(l==r)
     72     {
     73         sum[rt]=tree[que[l]];
     74         return;
     75     }
     76     int mid=(l+r)>>1;
     77     build(lson);
     78     build(rson);
     79     pushup(rt);
     80 }
     81 
     82 void update(int L,int R,ll val,int l,int r,int rt)
     83 {
     84     if(L<=l && r<=R)
     85     {
     86         lazy[rt]+=val;
     87         sum[rt]+=val;
     88         return;
     89     }
     90     int mid=(l+r)>>1;
     91     pushdown(rt);
     92     if(L<=mid)
     93     {
     94         update(L,R,val,lson);
     95     }
     96     if(mid<R)
     97     {
     98         update(L,R,val,rson);
     99     }
    100     pushup(rt);
    101 }
    102 ll query(int L,int R,int l,int r,int rt)
    103 {
    104     if(L<=l && r<=R)
    105     {
    106         return sum[rt];
    107     }    
    108     pushdown(rt);
    109     int mid=(l+r)>>1;
    110     ll ans=-linf;
    111     if(L<=mid)
    112     {
    113         ans=max(ans,query(L,R,lson));
    114     }
    115     if(mid<R)
    116     {
    117         ans=max(ans,query(L,R,rson));
    118     }
    119     return ans;
    120 }
    121 int main()
    122 {
    123     int T;
    124     scanf("%d",&T);
    125     int cas=0;
    126     while(T--)
    127     {
    128         scanf("%d%d",&n,&m);
    129         init();
    130         int u,v;
    131         for(int i=1;i<=n-1;i++)
    132         {
    133             scanf("%d%d",&u,&v);
    134             u++;v++;
    135             addedge(u,v);
    136             addedge(v,u); 
    137         }
    138         for(int i=1;i<=n;i++)
    139         {
    140             scanf("%I64d",&a[i]);        
    141         }    
    142         tree[1]=a[1];
    143         dfs(1,-1);
    144         build(1,cid,1);
    145         printf("Case #%d:
    ",++cas);
    146         while(m--)
    147         {
    148             int tp;
    149             scanf("%d",&tp);
    150             if(tp==0)
    151             {
    152                 int x;ll val;
    153                 scanf("%d%I64d",&x,&val);
    154                 x++;
    155                 update(st[x],ed[x],val-a[x],1,cid,1);
    156                 a[x]=val;
    157             }
    158             else
    159             {
    160                 int x;scanf("%d",&x);x++;
    161                 ll ans=query(st[x],ed[x],1,cid,1);
    162                 printf("%I64d
    ",ans);
    163             }
    164         }
    165     }    
    166     return 0;
    167 } 
    View Code

     【注意】

    线段树要开4倍空间,因为这个WA了好久

  • 相关阅读:
    Java异常
    JS多个对象添加到一个对象中
    JSON.parse(),JSON.stringify(),jQuery.parseJSON()
    java中什么是序列化和反序列化
    html颜色字体字符代码
    冒泡排序应用
    HTML 速查列表
    html初学(一)
    html初学(二)
    一次、二次、三次指数平滑计算思想及代码
  • 原文地址:https://www.cnblogs.com/itcsl/p/7421977.html
Copyright © 2020-2023  润新知