DFS序+线段树(bzoj 4034)

题目就不多说了。
本题目,可以用dfs序+线段树做:题目给定了一棵树,树上节点告诉了权值。我们可以先将这棵树进行dfs将一棵树变成线性结构:如图

变成这样后,然后就可以用线段树。
  • 操作1:也就是将某两个点+a;
  • 操作2:区间更新
  • 操作3:查询起始区间到某点的和
我们建线段树,需要统计 +,- 抵消后的个数,因为要知道该区间的和,需要知道+a;
简单插线问线。
代码---参考下面链接吧或者我的
友情提示:注意爆int,计算的时候注意是否超int范围;所以wa了好多次。。。
  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cctype>
  4 #include <cmath>
  5 #include <set>
  6 #include <map>
  7 #include <list>
  8 #include <queue>
  9 #include <deque>
 10 #include <stack>
 11 #include <string>
 12 #include <vector>
 13 #include <iostream>
 14 #include <algorithm>
 15 #include <stdlib.h>
 16 #include <time.h>
 17 using namespace std;
 18 typedef long long LL;
 19 const int INF=2e9+1e8;
 20 
 21 const int MOD=1e9+7;
 22 const double eps=0.0000000001;
 23 void fre()
 24 {
 25     freopen("test.in","r",stdin);
 26     freopen("test.out","w",stdout);
 27 }
 28 #define MSET(a,b) memset(a,b,sizeof(a))
 29 
 30 const int maxn=1e6+10;
 31 void zpsb(int x)
 32 {
 33     if(x>=0&&x<maxn) return ;
 34     while(1);
 35 }
 36 struct Edge 
 37 {
 38     int t,next;
 39 }edge[maxn];
 40 int sz,first[maxn],Treeval[maxn];
 41 void addedge(int s,int t)
 42 {
 43     edge[sz].t=t,edge[sz].next=first[s];
 44     first[s]=sz++;
 45 }
 46 int in[maxn],out[maxn];
 47 int reid[maxn],io[maxn],tot;
 48 void dfs(int x,int pre)
 49 {
 50     reid[in[x]=tot]=Treeval[x];
 51     io[tot++]=1;
 52     for(int i=first[x];i!=-1;i=edge[i].next)
 53     {
 54         int t=edge[i].t;
 55         if(t==pre) continue;
 56         dfs(t,x);
 57     }
 58     reid[out[x]=tot]=-Treeval[x];
 59     io[tot++]=-1;
 60 }
 61 
 62 
 63 struct SegTree 
 64 {
 65     struct Node 
 66     {
 67         int l,r,flag;
 68         LL lazy,sum;
 69     }T[maxn*4];
 70     void build(int i,int l,int r)
 71     {
 72         T[i].l=l,T[i].r=r;
 73         T[i].lazy=T[i].flag=0;
 74         if(l==r) 
 75         {
 76             T[i].sum=reid[r];
 77             T[i].flag=io[r];
 78             return ;
 79         }
 80         int mid=(l+r)>>1;
 81         build(i<<1,l,mid),build(i<<1|1,mid+1,r);
 82         T[i].sum=T[i<<1].sum+T[i<<1|1].sum;
 83         T[i].flag=T[i<<1].flag+T[i<<1|1].flag;
 84     }
 85     void pushdown(int i)
 86     {
 87         if(T[i].lazy)
 88         {
 89             T[i<<1].sum+=T[i].lazy*T[i<<1].flag;
 90             T[i<<1|1].sum+=T[i].lazy*T[i<<1|1].flag;
 91             T[i<<1].lazy+=T[i].lazy,T[i<<1|1].lazy+=T[i].lazy;
 92             T[i].lazy=0;
 93         }
 94     }
 95     void update(int i,int l,int r,LL k)
 96     {
 97         zpsb(i);
 98         if(T[i].l==l&&T[i].r==r)
 99         {
100             T[i].sum+=T[i].flag*k;
101             T[i].lazy+=k;
102             return ;
103         }
104         pushdown(i);
105         int mid=(T[i].l+T[i].r)>>1;
106         if(r<=mid) update(i<<1,l,r,k);
107         else if(l>mid) update(i<<1|1,l,r,k);
108         else update(i<<1,l,mid,k),update(i<<1|1,mid+1,r,k);
109         T[i].sum=T[i<<1].sum+T[i<<1|1].sum;
110     }
111     LL query(int i,int l,int r)
112     {
113         if(T[i].l==l&&T[i].r==r) return T[i].sum;
114         pushdown(i);
115         int mid=(T[i].l+T[i].r)>>1;
116         if(r<=mid) return query(i<<1,l,r);
117         else if(l>mid) return query(i<<1|1,l,r);
118         else return query(i<<1,l,mid)+query(i<<1|1,mid+1,r);
119     }
120 }wa;
121 int main()
122 {
123     int n,m;
124     MSET(first,-1);
125     sz=0;
126     scanf("%d%d",&n,&m);
127     for(int i=1;i<=n;i++)
128         scanf("%d",&Treeval[i]);
129     for(int i=2;i<=n;i++)
130     {
131         int x,y;
132         scanf("%d%d",&x,&y);
133         addedge(x,y);
134         addedge(y,x);
135     }
136     tot=1;
137     dfs(1,1);
138     // for(int i=1;i<=n;i++)
139     // {
140     //     printf("x=%d %d %d
",i,in[i],out[i]);
141     // }
142     // for(int i=1;i<=2*n;i++)
143     // {
144     //     printf("id=%d val=%d
",i,reid[i]);
145     // }
146     wa.build(1,1,2*n);
147     while(m--)
148     {
149         int opt;
150         scanf("%d",&opt);
151         if(opt==1)
152         {
153             int x,a;
154             scanf("%d%d",&x,&a);
155             wa.update(1,in[x],in[x],(LL)a);
156             wa.update(1,out[x],out[x],(LL)a);
157         }
158         else if(opt==2)
159         {
160             int x,a;
161             scanf("%d%d",&x,&a);
162             wa.update(1,in[x],out[x],(LL)a);
163         }
164         else 
165         {
166             int x;
167             scanf("%d",&x);
168             printf("%lld
",wa.query(1,1,in[x]));
169         }
170     }
171 }
172 
173 
174 /**************************************************/
175 /**             Copyright Notice                 **/
176 /**  writer: wurong                              **/
177 /**  school: nyist                               **/
178 /**  blog  : http://blog.csdn.net/wr_technology  **/
179 /**************************************************/


原文地址:https://www.cnblogs.com/coded-ream/p/7207915.html