Question link ~~>
Question recognition:This question is really clever. After an analysis of the mysteries of the question, I felt a lot of GAINS.
Solution:
First, we need to split the tree into chains. The idea is similar to that of HDU 5044, but instead of array traversal, the line segment tree replaces the array. If you dye in the range of [a, B], you can add this color to node A and subtract the color from Node B + 1. Then you can traverse the array, however, each node can dye many colors, so it cannot be traversed only once like an array. We can get those vertices to the line segment tree so that we only need to update the vertices on the online segment tree, the color obtained each time must be the color of the root node of the line segment.
Code:
# Pragma comment (linker, "/Stack: 1024000000,1024000000 ") # include <iostream> # include <sstream> # include <map> # include <cmath> # include <fstream> # include <queue> # include <vector> # include <sstream> # include <cstring> # include <cstdio> # include <stack> # include <bitset> # include <ctime> # include <string> # include <cctype> # include <iomanip> # include <algorithm> using namespace STD; # define int _ int64 # define L (x) (x * 2) # define R (x) (X * 2 + 1) const int INF = 0x3f3f3f3f; const double ESP = 0.0000000001; const double Pi = ACOs (-1.0); const int mod = 1000000007; const int my = 1400 + 5; const int MX = 100000 + 5; int n, m, num, idx, maxn; int head [MX], Father [MX], ti [MX], top [MX], DEP [MX], siz [MX], son [MX], ANS [MX], p [MX]; struct edge // The {int V, next;} e [MX * 2]; struct node {int U, V, W; node (){}; node (INT _ u, int _ V, in T _ w): U (_ u), V (_ v), w (_ w) {};}; vector <node> st; vector <int> G [MX]; void addedge (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; siz [u] = 1; son [u] = 0; father [u] = fa; 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) ;}} void LCA (int u, int V, int W) {While (top [u]! = Top [v]) {If (DEP [top [u] <Dep [top [v]) Swap (u, v); ST. push_back (node (Ti [top [u], Ti [u] + 1, W); U = Father [top [u];} if (DEP [u]> Dep [v]) Swap (u, v); ST. push_back (node (Ti [u], Ti [v] + 1, W);} struct node {int le, RT, num, type ;} T [MX * 4]; void build (int x, int le, int RT) // build {T [X]. num = 0; t [X]. le = Le; t [X]. RT = RT; If (Le = RT) {T [X]. type = Le; return;} int mid = (le + RT)> 1; build (L (x), Le, mid); Build (R (x ), mid + 1, RT);} void push_up (int x) {T [X]. num = max (T [L (x)]. num, t [R (x)]. num); If (T [L (x)]. num> = T [R (x)]. num) T [X]. type = T [L (x)]. type; else t [X]. type = T [R (x)]. type;} void Update (int x, int POs, int add) {If (T [X]. le = T [X]. RT) {T [X]. num + = add; return;} int mid = (T [X]. le + T [X]. RT)> 1; if (Pos <= mid) Update (L (x), POs, add); else Update (R (x), POs, add ); push_up (x);} void Init () {num = 0; memset (Head,-1, sizeof (head); memset (ANS, 0, sizeof (ANS )); memset (p, 0, sizeof (p); ST. clear (); For (INT I = 0; I <= n + 1; ++ I) g [I]. clear () ;}int main () {// freopen ("input.txt", "r", stdin); int U, V, W; while (scanf ("% d", & N, & M), N + M) {Init (); For (INT I = 1; I <N; ++ I) {scanf ("% d", & U, & V); addedge (u, v );} // tree link partitioning Dep [1] = siz [0] = 0; dfs_find (1, 1); idx = 1; dfs_time (1, 1); maxn = 1; for (INT I = 1; I <= N; ++ I) // convert node No. P [Ti [I] = I; for (INT I = 0; I <m; ++ I) // process the query {scanf ("% d", & U, & V, & W); LCA (u, v, w); maxn = max (W, maxn);} build (1, 1, maxn); // build int size = ST. size (); For (INT I = 0; I <size; ++ I) // process {int u = sT [I]. u, v = sT [I]. v, W = sT [I]. w; G [u]. push_back (w); G [v]. push_back (-W) ;}for (INT I = 1; I <= N; ++ I) // uses the prefix idea to traverse each node in sequence, node {sort (G [I]. begin (), g [I]. end (); For (Int J = 0; j <(INT) g [I]. size (); ++ J) // insert each node {int color = G [I] [J]; If (color <0) Update (1,-color, -1); else update (1, color, 1);} If (T [1]. num) ans [p [I] = T [1]. type; else ans [p [I] = 0 ;}for (INT I = 1; I <= N; ++ I) printf ("% d \ n ", ans [I]);} return 0 ;}
HDU 5029 relief grain (tree link splitting)