Snacks

Snacks

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

dfs序+线段树

这道题涉及到对整棵树的值修改,考虑将树状结构用dfs序转化成线性结构,将树的修改转化为区间修改以降低时间复杂度(之前组队赛的时候遇到一道类似的没调出来...代码能力太缺乏了...)

代码如下:

  1 #include<cstdio>
  2 #include<vector>
  3 #include<iostream>
  4 #include<cstring>
  5 #pragma comment(linker, "/STACK:1024000000,1024000000")
  6 #define LL long long
  7 #define N 100100
  8 #define lson (x<<1)
  9 #define rson (x<<1|1)
 10 #define mid ((l+r)>>1)
 11 using namespace std;
 12 struct node{
 13     LL sum,lazy;
 14 }a[N<<2];
 15 LL val[N];
 16 int L[N],R[N];
 17 LL spre[N];
 18 int index;
 19 bool vis[N];
 20 vector<int>e[N];
 21 void init(){
 22     //for(int i=0;i<N;++i)e[i].clear();
 23     //memset(a,0,sizeof(a));
 24     memset(vis,0,sizeof(vis));
 25     memset(L,0,sizeof(L));
 26     memset(R,0,sizeof(R));
 27     memset(val,0,sizeof(val));
 28     memset(spre,0,sizeof(spre));
 29     index=0;
 30 }
 31 void dfs(int num,LL v){
 32     vis[num]=1;
 33     ++index;
 34     L[num]=index;
 35     for(LL i=0;i<e[num].size();i++)
 36         if(!vis[e[num][i]])dfs(e[num][i],v+val[e[num][i]]);
 37     e[num].clear();
 38     spre[L[num]]=v;
 39     R[num]=index;
 40 }
 41 void push_up(int x){
 42     a[x].sum=max(a[lson].sum,a[rson].sum);
 43 }
 44 void push_down(int x){
 45     a[rson].sum+=a[x].lazy;
 46     a[rson].lazy+=a[x].lazy;
 47     a[lson].sum+=a[x].lazy;
 48     a[lson].lazy+=a[x].lazy;
 49     a[x].lazy=0;
 50 }
 51 void build(int x,int l,int r){
 52     a[x].lazy=a[x].sum=0;
 53     if(l==r){
 54         a[x].sum=spre[l];
 55         return;
 56     }
 57     build(lson,l,mid);
 58     build(rson,mid+1,r);
 59     push_up(x);
 60 }
 61 void add(int x,int l,int r,int cl,int cr,LL v){
 62     if(cl<=l&&r<=cr){
 63         a[x].sum+=v;
 64         a[x].lazy+=v;
 65         return;
 66     }
 67     if(a[x].lazy!=0)push_down(x);/**except this!!!**/
 68     if(cl<=mid)add(lson,l,mid,cl,cr,v);
 69     if(mid<cr)add(rson,mid+1,r,cl,cr,v);
 70     push_up(x);
 71 }
 72 LL query(int x,int l,int r,int ql,int qr){
 73     if(ql<=l&&r<=qr)return a[x].sum;
 74     if(a[x].lazy!=0)push_down(x);
 75     LL temp=-(LL)1000000000000000000;
 76     if(ql<=mid)temp=max(temp,query(lson,l,mid,ql,qr));
 77     if(mid<qr)temp=max(temp,query(rson,mid+1,r,ql,qr));
 78     return temp;
 79 }
 80 int main(void){
 81     int T,n,m;
 82     scanf("%d",&T);
 83     for(int i=1;i<=T;++i){
 84       /*if(i==10)while(1);
 85         WA when i==10*/
 86         init();
 87         scanf("%d%d",&n,&m);
 88         for(int j=1;j<n;++j){
 89             int x,y;
 90             scanf("%d%d",&x,&y);x++,y++;
 91             e[x].push_back(y);
 92             e[y].push_back(x);
 93         }
 94         for(int j=1;j<=n;++j)
 95             scanf("%I64d",&val[j]);
 96         dfs(1,val[1]);
 97         build(1,1,n);
 98         printf("Case #%d:
",i);
 99         while(m--){
100             int type;
101             scanf("%d",&type);
102             if(type==0){
103                 int x,v;
104                 scanf("%d%d",&x,&v);x++;
105                 LL diff=(LL)v-val[x];
106                 val[x]=(LL)v;
107                 add(1,1,n,L[x],R[x],diff);
108             }else if(type==1){
109                 int x;
110                 scanf("%d",&x);x++;
111                 LL temp=query(1,1,n,L[x],R[x]);
112                 printf("%I64d
",temp);
113             }
114         }
115     }
116     return 0;
117 }
原文地址:https://www.cnblogs.com/barrier/p/5831927.html