Topic Link ~~>
To do the idea : after the regional game did not write the tree, only remember the thought, the game thought, but only to play the code for more than half an hour (really drunk!!) ), and then is the constant debugging code, the sad reminder is the tune for one hours also did not tune out .....
problem-solving ideas: This problem as long as the thought of a node of the subtree of all the node number is greater than the number of this node (in the line segment tree) and is continuous, then we only need to deep search the tree at a time of the largest node timestamp (the number in the segment tree), As long as we use the time stamp of a node and the time stamp to go out to the sub-tree operation of the node (cf has a processing sub-tree similar to the problem), the other two operations so easy, the line tree is written down, please forgive me ...
Code:
#pragma COMMENT (linker, "/stack:102400000,102400000") #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map># Include <set> #include <stdio.h> #include <vector> #define L (x) (x*2) #define R (x) (x*2 + 1) using namespace Std;const int INF = 0x3f3f3f3f; const int MX = 100000 + 5; int n, M, num, idx, sum; int dep[mx], top[mx], v[mx] , Ti[mx], to[mx], head[mx], father[mx], siz[mx], son[mx]; struct edge{int V, Next;} E[MX*2]; void Add_edge (int u, int v) {e[num].v = v; E[num].next = Head[u]; Head[u] = num++; E[NUM].V = u; E[num].next = Head[v]; HEAD[V] = num++;} void Dfs_find (int u, int fa) {Dep[u] = Dep[fa] + 1; Father[u] = FA; Siz[u] = 1; Son[u] = 0; for (int i = head[u]; i =-1; i = e[i].next) {int v = E[I].V; if (v = = FA) continue; Dfs_find (V, u); Siz[u] + = Siz[v]; if (Siz[son[u]] < SIZ[V]) Son[u] = v; }}void dfs_time (int u, int fa) {Ti[u] = idx++; Top[u] = FA; if (Son[u]) dfs_time (Son[u], top[u]); for (int i = head[u]; i =-1; i = e[i].next) {int v = E[I].V; if (v = = Father[u] | | v = = Son[u]) continue; Dfs_time (V, v); } To[u] = idx-1;} void init () {sum = 0; num = 0; memset (head, -1, sizeof (head));} Segment Tree---------------------struct node{int le, RT, SUM, Flag;} T[MX*4]; void build (int x, int le, int rt) {t[x].sum = 0; T[x].flag = true; T[x].le = le; T[x].rt = RT; if (le = = RT) return; int Mid = (le + rt) >>1; Build (L (x), Le, Mid); Build (R (x), mid+1, RT);} void push_up (int x) {t[x].sum = T[l (x)].sum + t[r (x)].sum; T[x].flag = true;} void Push_down (int x) {if (! T[x].flag) {t[l (x)].sum = t[r (x)].sum = 0; T[l (x)].flag = t[r (x)].flag = false; t[x].sum = 0; }}bool findpos (int x, int pos) {if (T[x].le = = T[x].rt && T[x].le = = pos) {if (! T[x].flag) t[x].sum = 0; return t[x].flag; } push_down (x); int Mid = (t[x].le + t[x].rt) >>1; if (POS <= Mid) return Findpos (L (x), POS); else return Findpos (R (x), POS); PUSH_UP (x);} void Insert (int x, int pos, int w)//modifier point {if (T[x].le = = T[x].rt && t[x].le = = pos) {t[x].sum = W; T[x].flag = true; return; } push_down (x); int Mid = (t[x].le + t[x].rt) >>1; if (POS <= Mid) Insert (L (x), POS, W); else Insert (R (x), POS, W); PUSH_UP (x);} void update (int x, int Le, int Rt)//interval clear 0 {if (t[x].le = = Le && T[x].rt = = Rt) {T[x].flag = false; t[x].sum = 0; return; } push_down (x); int Mid = (t[x].le + t[x].rt) >>1; if (Le > Mid) Update (R (x), Le, Rt); else if (Rt <= Mid) Update (L (x), Le, Rt); else {update (L (x), Le, Mid); Update (R (x), mid+1, Rt); } PUSH_UP (x);} int Query (int x, int Le, int Rt)//Interval sum {if (T[x].le = = Le && T[x].rt = = Rt) {if (! T[x].flag) t[x].sum = 0; int temp = T[x].sum; t[x].sum = 0; T[x].flag = false; return temp; } push_down (x); int Mid = (t[x].le + t[x].rt) >>1; if (Le > Mid) return Query (R (x), Le, Rt); else if (Rt <= Mid) return Query (L (x), Le, Rt); else return query (L (x), Le, Mid) + query (R (x), mid+1, Rt);} void LCA (int u, int v) {int temp; while (Top[u]! = Top[v]) {if (Dep[top[u]] < DEP[TOP[V]]) swap (U, v); temp = Query (1, Ti[top[u]], ti[u]); Update (1, Ti[top[u]], ti[u]); sum + = temp; U = father[top[u]]; } if (Dep[u] > Dep[v]) Swap (U, v); temp = Query (1, Ti[u], ti[v]); Update (1, Ti[u], ti[v]); sum + = temp;} int main () {//freopen ("Input.txt", "R", stdin); int Tx, u, v; scanf ("%d", &TX); while (tx--){init (); scanf ("%d", &n); for (int i = 1; I <= n; ++i) scanf ("%d", &v[i]); for (int i = 1; i < n; ++i) {scanf ("%d%d", &u, &v); Add_edge (U, v); } dep[1] = siz[0] = 0; Dfs_find (1, 1); IDX = 1; Dfs_time (1, 1); Build (1, 1, N); for (int i = 1; I <= n; ++i) Insert (1, ti[i], v[i]); scanf ("%d", &m); int type; for (int i = 0; i < m; ++i) {scanf ("%d%d", &type, &u); if (type = = 1) {scanf ("%d", &v); LCA (U, v); } else if (type = = 2) {BOOL flag = Findpos (1, ti[u]); if (!flag)//If False indicates already occupied {insert (1, Ti[u], v[u]); Sum-= V[u]; }} else if (type = = 3) { Sum + = Query (1, Ti[u], to[u]); Update (1, Ti[u], to[u]); } Cout<<sum<<endl; }} return 0;}
"Bestcoder" Cup Chinese university student Program Design Championship HDU 5221 occupation