Poj 3237 enhanced query on a tree

Source: Internet
Author: User

Link:

Http://www.spoj.pl/problems/QTREE/

Http://poj.org/problem? Id = 3237


Question: a tree, two update operations, change the edge weight of an edge, reverse all the edge weights of A-> B, and ask the maximum edge weight of a path.

These are all typical tree links. The following question is the enhanced version above. It is not difficult to perform segment update on the tree.

Only the interval must record a minimum value, because the inverse operation will swap the maximum value and the minimum value of the interval.

Then there is the old way of tree Chain Division. If it is heavy chain, it will be updated in the online segment tree; otherwise, edge weight will be changed directly.

When the line segment tree is put down with the lazy mark, it is missing. after a long time of adjustment, it will burst ....

It seems that we can use the dynamic tree to implement it. I have understood all the concepts, but I have never practiced it. I will learn it in another day and paste it.

The following is the code for these two questions. My code is a bit tricky--. Please be careful when watching, so as not to hurt your eyes *_*

Spoj 375 query on a tree

# Include <cstdio> # include <cstring> # include <algorithm> using namespace STD; # define lson L, M, RT <1 # define rson m + 1, R, RT <1 | 1 const int maxn = 20010; const int INF = ~ 0u> 2; int M [maxn <2]; struct node {int S, T, W, next;} edge [maxn * 2]; int e, N; int size [maxn], Fa [maxn], heavy [maxn], head [maxn], DEP [maxn], rev [maxn], num [maxn], cost [maxn]; int seg_size; inline void max (Int & X, int y) {If (x <Y) x = y;} int find (int x) {return x = Fa [x]? X: Fa [x] = find (Fa [x]);} void add_edge (int s, int T, int W) {edge [e]. W = W; edge [e]. S = s; edge [e]. T = T; edge [e]. next = head [s]; head [s] = e ++;} void DFS (int u, int f) {int MX =-1, E =-1; size [u] = 1; for (INT I = head [u]; I! =-1; I = edge [I]. next) {int v = edge [I]. t; If (V = f) continue; Dep [v] = Dep [u] + 1; rev [v] = I ^ 1; DFS (v, U ); size [u] + = size [v]; If (size [v]> MX) {MX = size [v]; E = I ;}} heavy [u] = E; If (E! =-1) Fa [edge [e]. t] = u;} inline void pushup (int rt) {M [RT] = max (M [RT <1], M [RT <1 | 1]);} void build (int l, int R, int RT) {M [RT] = inf; If (L = r) {return;} int M = (L + r)> 1; build (lson); Build (rson);} void Update (int p, int Val, int l, int R, int RT) {If (L = r) {M [RT] = val; return;} int M = (L + r)> 1; if (P <= m) Update (p, Val, lson); else Update (p, Val, rson); pushup (RT);} int query (INT l, int R, int L, int R, int RT) {If (L <= L && R <= r) {return M [RT];} int M = (L + r)> 1; int ret = 0; If (L <= m) ret = max (Ret, query (L, R, lson); If (r> m) ret = max (Ret, query (L, R, rson )); return ret;} void prepare () {build (1, n-1, 1); memset (Num,-1, sizeof (Num); Dep [0] = 0; seg_size = 0; For (INT I = 0; I <n; I ++) Fa [I] = I; DFS (0, 0); For (INT I = 0; I <n; I ++) {If (heavy [I] =-1) {int Pos = I; while (Pos & edge [heavy [edge [Rev [POS]. t]. T = POS) {int T = rev [POS]; num [T] = num [t ^ 1] = ++ Seg_size; Update (seg_size, edge [T]. w, 1, n-1, 1); Pos = edge [T]. t ;}}} void change (INT edge_id, int Val) {If (Num [edge_id] =-1) edge [edge_id]. W = edge [edge_id ^ 1]. W = val; else Update (Num [edge_id], Val, 1, n-1, 1);} int calc (int u, int LCA) {int ans =-INF; int Vi = 0; while (u! = LCA) {vi ++; If (Vi = 10) break; int r = rev [u]; If (Num [R] =-1) max (ANS, edge [R]. w), u = edge [R]. t; else {int P = Fa [u]; If (DEP [p] <Dep [LCA]) P = LCA; int L = num [R]; int r = num [heavy [p]; max (ANS, query (L, R, 1, n-1, 1); U = P ;}} return ans ;} int LCA (int u, int v) {While (1) {int A = find (U), B = find (V); if (a = B) return Dep [u] <Dep [v]? U: V; // A, B else if (DEP [a]> = Dep [B]) u = edge [Rev [a] on the same heavy chain. t; else v = edge [Rev [B]. t ;}} int solve (int u, int v) {int P = LCA (u, v); Return max (calc (u, P), Calc (V, p);} int main () {int T, I, A, B, C; scanf ("% d", & T); While (t --) {memset (Head,-1, sizeof (head); E = 0; scanf ("% d", & N); for (I = 0; I <n-1; I ++) {scanf ("% d", & A, & B, & C); A --; B --; add_edge (A, B, c); add_edge (B, A, C);} prepare (); char op [20]; while (scanf ("% s", op )! = EOF & strcmp (OP, "done") {If (OP [0] = 'C') {scanf ("% d", &, & C); change (A-1) * 2, c);} else {scanf ("% d", & A, & B ); printf ("% d \ n", solve (A-1, B-1) ;}}return 0 ;} /* 131 2 12 3 2 query 1 2 Change 1 3 query 1 2done13171 2 11 3 22 4 32 5 43 6 53 7 6 query 1 7 */


Poj 3237

# Include <cstdio> # include <cstring> # include <algorithm> using namespace STD; # define lson L, M, RT <1 # define rson m + 1, R, RT <1 | 1 const int maxn = 100010; const int INF = ~ 0u> 2; int M [maxn <2]; int MI [maxn <2]; int Col [maxn <2]; struct node {int S, T, w, next;} edge [maxn * 2]; int e, N; int size [maxn], Fa [maxn], heavy [maxn], head [maxn], dep [maxn], rev [maxn], num [maxn], cost [maxn]; int seg_size; inline void max (Int & X, int y) {If (x <Y) x = y;} inline int max (int A, int B) {return A> B? A: B;} inline int min (int A, int B) {return A> B? B: A;} int find (INT X) {return x = Fa [x]? X: Fa [x] = find (Fa [x]);} void add_edge (int s, int T, int W) {edge [e]. W = W; edge [e]. S = s; edge [e]. T = T; edge [e]. next = head [s]; head [s] = e ++;} void DFS (int u, int f) {int MX =-1, E =-1; size [u] = 1; for (INT I = head [u]; I! =-1; I = edge [I]. next) {int v = edge [I]. t; If (V = f) continue; Dep [v] = Dep [u] + 1; rev [v] = I ^ 1; DFS (v, U ); size [u] + = size [v]; If (size [v]> MX) {MX = size [v]; E = I ;}} heavy [u] = E; If (E! =-1) Fa [edge [e]. t] = u;} void build (int l, int R, int RT) {mi [RT] = inf; m [RT] =-INF; col [RT] = 0; If (L = r) {return;} int M = (L + r)> 1; build (lson ); build (rson);} inline void pushup (int rt) {M [RT] = max (M [RT <1], M [RT <1 | 1]); mi [RT] = min (MI [RT <1], MI [RT <1 | 1]);} void make (int rt) {int TMP = mi [RT]; MI [RT] =-M [RT]; m [RT] =-TMP;} void Pushdown (int rt) {If (COL [RT]) {Col [RT <1] ^ = 1; make (RT <1 ); col [RT <1 | 1] ^ = 1; make (RT <1 | 1); Col [RT] = 0 ;/ /I haven't written a line segment tree for a long time. I forgot to even write this line.} void Update (INT P, int Val, int L, int R, int RT) {If (L = r) {mi [RT] = m [RT] = val; return;} Pushdown (RT); int M = (L + r)> 1; if (P <= m) Update (p, Val, lson); else Update (p, Val, rson); pushup (RT);} void justdoit (INT l, int R, int L, int R, int RT) {// printf ("L = % d r = % d l = % d r = % d \ n", l, r, L, R); If (L <= L & R <= r) {Col [RT] ^ = 1; make (RT); return ;} pushdown (RT); int M = (L + r)> 1; if (L <= m) justdoit (L, R, lson); If (r> m) justdoit (L, R, rson); pushup (RT);} int query (int l, int R, int L, int R, int RT) {If (L <= L & R <= r) {return M [RT];} Pushdown (RT); int M = (L + r)> 1; int ret =-INF; If (L <= m) ret = max (Ret, query (L, R, lson); If (r> m) ret = max (Ret, query (L, R, rson); return ret;} void prepare () {build (1, n-1, 1); memset (Num, -1, sizeof (Num); Dep [0] = 0; seg_size = 0; For (INT I = 0; I <n; I ++) fa [I] = I; DFS (0, 0); For (INT I = 0; I <n; I ++) {If (heavy [I] =-1) {int Pos = I; while (Pos & edge [Heavy [edge [Rev [POS]. t]. T = POS) {int T = rev [POS]; num [T] = num [t ^ 1] = ++ seg_size; Update (seg_size, edge [T]. w, 1, n-1, 1); Pos = edge [T]. t ;}}} void change (INT edge_id, int Val) {If (Num [edge_id] =-1) edge [edge_id]. W = edge [edge_id ^ 1]. W = val; else Update (Num [edge_id], Val, 1, n-1, 1);} int calc (int u, int LCA) {int ans =-INF; while (u! = LCA) {int r = rev [u]; If (Num [R] =-1) max (ANS, edge [R]. w), u = edge [R]. t; else {int P = Fa [u]; If (DEP [p] <Dep [LCA]) P = LCA; int L = num [R]; int r = num [heavy [p]; max (ANS, query (L, R, 1, n-1, 1); U = P ;}} return ans ;} void Gao (int u, int LCA) {While (u! = LCA) {int r = rev [u]; If (Num [R] =-1) edge [R]. W = edge [R ^ 1]. W =-edge [R]. w, u = edge [R]. t; else {int P = Fa [u]; If (DEP [p] <Dep [LCA]) P = LCA; int L = num [R]; int r = num [heavy [p]; // printf ("L = % d r = % d \ n", l, R); justdoit (L, R, 1, n-1, 1); U = P ;}}} int LCA (int u, int v) {While (1) {int A = find (u ), B = find (V); if (a = B) Return Dep [u] <Dep [v]? U: V; // A, B else if (DEP [a]> = Dep [B]) u = edge [Rev [a] on the same heavy chain. t; else v = edge [Rev [B]. t ;}} int solve (int u, int v) {int P = LCA (u, v); Return max (calc (u, P), Calc (V, p);} void Sol (int u, int v) {int P = LCA (u, v); // printf ("P = % d \ n ", p); Gao (u, P); Gao (V, p) ;}int main () {int T, I, A, B, C; scanf ("% d", & T); While (t --) {memset (Head,-1, sizeof (head); E = 0; scanf ("% d", & N); for (I = 0; I <n-1; I ++) {scanf ("% d", &, & B, & C); A --; B --; add_edge (A, B, C); Ad D_edge (B, A, c) ;}prepare (); char op [20]; while (scanf ("% s", OP )! = EOF & strcmp (OP, "done") {If (OP [0] = 'C') {scanf ("% d", &, & C); change (A-1) * 2, c);} else if (OP [0] = 'n') {scanf ("% d ", & A, & B); if (a = B) while (1); SOL (A-1, B-1);} else {scanf ("% d ", & A, & B); if (a = B) while (1); printf ("% d \ n", solve (A-1, B-1 ));}}} return 0 ;}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.