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\n",i,in[i],out[i]); 141 // } 142 // for(int i=1;i<=2*n;i++) 143 // { 144 // printf("id=%d val=%d\n",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\n",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 /**************************************************/