• the meaning of problems
There are a number of points N of the tree is the root to the point, and the right side has a tree points.
Then there are M operations, divided into three types:
Action 1: the right point of a node x increases a.Operation 2: The subtree rooted at some node x of weights of all points are point increases a.Operation 3: interrogation points right path to a node x to the root node and all.3 corresponds to the output operation of the answer;
•answer
If the tree structure can be converted into a chain structure, then, the operation 2 can be used to maintain the segment tree;
$1,2,4,4,5,5,2,3,3,1$
Defined $ s, e $ are recorded position of each node in the sequence and position of the first occurrence of the last occurrence;
So, the position of the first occurrence of the right is positive, the position of the last occurrence of the right value is negative;
In this case, it can be maintained through the tree line;
Operation 1 corresponds to a single point in the segment tree update operations;
2 corresponds to the operation section in the segment tree updating operation;
3 is the operating range query;
•Code
View Code1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ls(x) (x<<1) 5 #define rs(x) (x<<1|1) 6 #define mem(a,b) memset(a,b,sizeof(a)) 7 const int maxn=1e5+50; 8 9 int n,m; 10 int a[maxn]; 11 int num; 12 int head[maxn]; 13 struct Edge 14 { 15 intto; 16 int Next; . 17 } G [MAXN << . 1 ]; 18 is void addEdge ( int U, int V) . 19 { 20 is G [NUM] = {V, head [U]}; 21 is head [U] = NUM ++ ; 22 is } 23 is struct Seg 24 { 25 int L, R & lt; 26 is LL the lazy; 27 LL SUM; 28 int X; /// in the direction of the leaf node number 29 int Y; /// number of the root node in the direction 30 int MID () { return L + ((rl is an) >> . 1 );} 31 is void the Set (LL Val) 32 { 33 is /// If [l, r] of each node have increased interval Val 34 is /// less, [l, r] interval along the x direction leaf nodes increases Val + 35 /// [l, r] interval in the y direction is the root node increases -Val 36 the lazy + = Val; 37 [ SUM = 1LL + * (XY) * Val; 38 is } 39 } SEG [<< MAXN . 3 ]; 40 int CNT; 41 is int S [MAXN]; 42 is int E [MAXN]; 43 is int vs[maxn<<1]; 44 bool g[maxn<<1]; 45 46 void DFS(int u,int f) 47 { 48 vs[++cnt]=u; 49 s[u]=cnt; 50 g[cnt]=1; 51 for(int i=head[u];~i;i=G[i].next) 52 { 53 int v=G[i].to; 54 if(v != f) 55 DFS(v,u); 56 } 57 vs [++ CNT] = l; 58 e [u] = CNT; 59 g [CNT] = 0 ; 60 } 61 void pushUp ( int gum) 62 { 63 seg [gum] .x = seg [ls (gum)]. X + seg [rs (gum)]. X; 64 seg [gum] .y = seg [ls (gum)]. Y + seg [rs (gum)]. Y; 65 seg [gum] .sum = seg [ls (gum)]. Sum + seg [rs (gum)]. Sum; 66 } 67 void pushDown ( int gum) 68 { 69 ll & lazy = seg [gum] .lazy; 70 if(!lazy) 71 return ; 72 73 seg[ls(pos)].Set(lazy); 74 seg[rs(pos)].Set(lazy); 75 76 lazy=0; 77 } 78 void build(int l,int r,int pos) 79 { 80 seg[pos]={l,r,0,0,0,0}; 81 82 if(l == r) 83 { 84 if(g[l]) 85 { 86 seg[pos].x++; 87 seg[pos].sum=a[vs[l]]; 88 } 89 else 90 { 91 seg[pos].y++; 92 seg[pos].sum=-a[vs[l]]; 93 } 94 95 return ; 96 } 97 98 int mid=seg[pos].mid(); 99 build(l,mid,ls(pos)); 100 build(mid+1,r,rs(pos)); 101 102 pushUp(pos); 103 } 104 void update(int pos,int l,int r,int x) 105 { 106 if(seg[pos].l == l && seg[pos].r == r) 107 { 108 seg[pos].Set(x); 109 return ; 110 } 111 pushDown(pos); 112 113 int mid=seg[pos].mid(); 114 if(r <= mid) 115 update(ls(pos),l,r,x); 116 else if(l > mid) 117 update(rs(pos),l,r,x); 118 else 119 { 120 update(ls(pos),l,mid,x); 121 update(rs(pos),mid+1,r,x); 122 } 123 pushUp(pos); 124 } 125 ll query(int pos,int l,int r) 126 { 127 if(seg[pos].l == l && seg[pos].r == r) 128 return seg[pos].sum; 129 pushDown(pos); 130 131 int mid=seg[pos].mid(); 132 if(r <= mid) 133 return query(ls(pos),l,r); 134 else if(l > mid) 135 return query(rs(pos),l,r); 136 else 137 return query(ls(pos),l,mid)+query(rs(pos),mid+1,r); 138 } 139 void Solve() 140 { 141 cnt=0; 142 DFS(1,1); 143 build(1,cnt,1); 144 145 while(m--) 146 { 147 int op; 148 scanf("%d",&op); 149 if(op == 1) 150 { 151 int u,x; 152 scanf("%d%d",&u,&x); 153 update(1,s[u],s[u],x); 154 update(1,e[u],e[u],x); 155 } 156 else if(op == 2) 157 { 158 int u,x; 159 scanf("%d%d",&u,&x); 160 update(1,s[u],e[u],x); 161 } 162 else 163 { 164 int u; 165 scanf("%d",&u); 166 printf("%lld\n",query(1,s[1],s[u])); 167 } 168 } 169 } 170 void Init() 171 { 172 num=0; 173 mem(head,-1); 174 } 175 int main() 176 { 177 // freopen("C:\\Users\\hyacinthLJP\\Desktop\\C++WorkSpace\\in&&out\\contest","r",stdin); 178 scanf("%d%d",&n,&m); 179 for(int i=1;i <= n;++i) 180 scanf("%d",a+i); 181 182 Init(); 183 for(int i=1;i < n;++i) 184 { 185 int u,v; 186 scanf("%d%d",&u,&v); 187 addEdge(u,v); 188 addEdge(v,u); 189 } 190 Solve(); 191 192 return 0; 193 }
• deformation
This problem may also be changed to solve the operation 3 $ u, and the node between the weights v $ path;
Just add a code to solve the $ LCA $ to the basis of the original;