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

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

    题目说每个点至多经过一次,那么就是只能一条路线走到底的意思,看到这题的格式,

    多个询问多个更新,

    自然而然的就会想到线段树或者树状数组,在建树前先做处理,

    用DFS将从起点0出发到任一点的距离求出,

    然后将这些节点按照一条一条完整的路线的顺序建到树中,

    比如样例是1---2---3         

                  |

          6 ---4----5

    所以建树的其中一种顺序是1 4 5 6 2 3 。当查询的时候的区间应该是从现在这个点开始到这条路线上的终点,更新的时候也是这个区间更新,相当于把这个区间的所有数都加上一个数,与 poj 3468 类似,lazy操作。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 using namespace std;
      6 
      7 typedef long long ll;
      8 const int M = 1e5 + 10;
      9 int head[M],cas,num[M],ans,st[M],ed[M];
     10 ll sum[M],a[M];
     11 
     12 ll max(ll x,ll y) {return x>y?x:y;}
     13 
     14 struct Edge{
     15    int to;
     16    int next;
     17 }edge[M*2];
     18 
     19 void add(int x,int y)
     20 {
     21     edge[cas].to=x;
     22     edge[cas].next=head[y];
     23     head[y]=cas++;
     24 }
     25 
     26 void dfs(int x,int y)
     27 {
     28     st[x]=++ans;num[ans]=x;
     29     sum[x]+=sum[y];
     30     for (int i=head[x] ; i!=-1 ; i=edge[i].next)
     31     {
     32         int v=edge[i].to;
     33         if (v==y) continue;
     34         dfs(v,x);
     35     }
     36     ed[x]=ans;
     37 }
     38 struct Tree{
     39     int l,r;
     40     ll ans,mark;
     41 }tree[M*4];
     42 
     43 void down(int i)
     44 {
     45     if(tree[i].mark)
     46     {
     47         tree[i*2].mark+=tree[i].mark;tree[i*2+1].mark+=tree[i].mark;
     48         tree[i*2].ans+=tree[i].mark;tree[i*2+1].ans+=tree[i].mark;
     49         tree[i].mark=0;
     50     }
     51 }
     52 
     53 void build(int i,int left,int right)
     54 {
     55     tree[i].l=left;tree[i].r=right;
     56     tree[i].mark=0;
     57     if (left==right){tree[i].ans=sum[num[left]];return ;}
     58     int mid=(left+right)/2;
     59     build(i*2,left,mid);
     60     build(i*2+1,mid+1,right);
     61     tree[i].ans=max(tree[i*2].ans,tree[i*2+1].ans);
     62 }
     63 
     64 ll findest(int i,int left,int right)
     65 {
     66     if(tree[i].l>=left&&tree[i].r<=right)
     67         return tree[i].ans;
     68     down(i);
     69     int mid=(tree[i].l+tree[i].r)/2;
     70     if(mid>=right){return findest(i*2,left,right);}
     71     else if(mid<left){return findest(i*2+1,left,right);}
     72     else{return max(findest(i*2,left,mid),findest(i*2+1,mid+1,right));}
     73 
     74 }
     75 void update(int i,int left,int right,ll pos)
     76 {
     77     if(tree[i].l>=left&&tree[i].r<=right){tree[i].mark+=pos;tree[i].ans+=pos;return;}
     78     int mid=(tree[i].l+tree[i].r)/2;
     79     down(i);
     80     if(mid<left) update(i*2+1,left,right,pos);
     81     else if(mid>=right) update(i*2,left,right,pos);
     82     else
     83     {
     84         update(i*2,left,mid,pos);
     85         update(i*2+1,mid+1,right,pos);
     86     }
     87     tree[i].ans=max(tree[i*2].ans,tree[i*2+1].ans);
     88 }
     89 
     90 int main()
     91 {
     92     int t,n,m,e=0;
     93     scanf("%d",&t);
     94     while (t--)
     95     {
     96         printf("Case #%d:
    ",++e);
     97         scanf("%d%d",&n,&m);
     98         memset(head,-1,sizeof(head));
     99         for (int i=1 ; i<n ; i++){
    100             int a,b;
    101             scanf("%d%d",&a,&b);
    102             a++,b++;
    103             add(a,b);add(b,a);
    104         }
    105         cas=0;ans=0;
    106         for (int i=1 ; i<=n ; i++) scanf("%I64d",&a[i]),sum[i]=a[i];
    107         dfs(1,0);
    108         build(1,1,n);
    109         while (m--)
    110         {
    111             int w,b;ll c;
    112             scanf("%d",&w);
    113             if (w){
    114                 scanf("%d",&b);b++;
    115                 printf("%I64d
    ",findest(1,st[b],ed[b]));
    116             }
    117             else{
    118                 scanf("%d%I64d",&b,&c);b++;
    119                 ll q=c-a[b];
    120                 a[b]=c;
    121                 update(1,st[b],ed[b],q);
    122             }
    123         }
    124     }
    125     return 0;
    126 }
    View Code

                                                                                                         

  • 相关阅读:
    页面跳转
    基于MCP2515的Linux CAN总线驱动程序设计(三)
    基于MCP2515的Linux CAN总线驱动程序设计(二)
    基于MCP2515的Linux CAN总线驱动程序设计(一)
    任意ASCII码格式信息的huffman tree压缩(编码)和解压(译码)
    转:Linux环境下段错误的产生原因及调试方法小结
    转:C语言中volatile关键字的作用 专家博客
    处理字节对齐
    转: sizeof,总结
    sizeof()用法汇总
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/5661693.html
Copyright © 2011-2022 走看看