HYSBZ 2243 tree link generation (Interval Update, interval query) is difficult, and hysbz2243
Http://www.lydsy.com/JudgeOnline/problem.php? Id = 2243
Description
Given a rootless tree with n nodes and m operations, there are two types of operations:
1. color all vertices from node a to Node B to c;
2. Ask about the number of color segments from node a to Node B (the same segment is regarded as continuous color). For example, "112221" consists of three segments: "11", "222", and "1 ".
Please write a program to complete the m operations in sequence.
Input
The first line contains two integers n and m, indicating the number of nodes and the number of operations respectively;
The second line contains n positive integers to indicate the initial color of n nodes.
Each line below contains two integers x and y, indicatingXAndYThere is a undirected edge between them.
Each line below describes an operation:
"C a B c" indicates that this is a dyeing operation. All vertices (including a and B) from node a to Node B are colored c;
"Q a B" indicates that this is an inquiry operation. It queries the number of color segments from node a to Node B (including a and B.
Output
Output a line of answers for each query operation.
Sample Input6 5
2 2 1 2 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5
Sample Output3
1
2
HINT
Number N <= 10 ^ 5, operand M <= 10 ^ 5, all colors C are integers and between [0, 10 ^ 9.
/*** How to solve the problem of HYSBZ 2243 tree link partitioning (Interval Update and interval query): After converting this question into a line segment tree, three values must be maintained: the color of the left boundary of the interval, the color of the right boundary of the interval. Pay attention to the deduplication technique during tree query. For details, see the code */# include <stdio. h> # include <string. h >#include <algorithm> # include <iostream> using namespace std; const int maxn = 100005; int fa [maxn], dep [maxn], siz [maxn], son [maxn], num [maxn], top [maxn]; int n, p, z, a [maxn], Hash [maxn]; int ll [maxn * 4], rr [maxn * 4], tree [maxn * 4], flag [maxn * 4]; int head [maxn], ip; void init () {memset (head, -1, sizeof (head); ip = 0;} struct note {int v, next;} edge [maxn * 2]; void addedg E (int u, int v) {edge [ip]. v = v, edge [ip]. next = head [u], head [u] = ip ++;} void dfs (int u, int pre) {son [u] = 0, siz [u] = 1, dep [u] = dep [pre] + 1, fa [u] = pre; for (int I = head [u]; I! =-1; I = edge [I]. next) {int v = edge [I]. v; if (v = pre) continue; dfs (v, u); siz [u] + = siz [v]; if (siz [son [u] <siz [v]) son [u] = v ;} // printf ("% d fa dep son siz % d \ n", u, fa [u], dep [u], son [u], siz [u]);} void init_que (int u, int tp) {num [u] = ++ z, top [u] = tp, Hash [z] = u; if (son [u]) {init_que (son [u], tp) ;}for (int I = head [u]; I! =-1; I = edge [I]. next) {int v = edge [I]. v; if (v = fa [u] | v = son [u]) continue; init_que (v, v );} // printf ("% d num top % d \ n", u, num [u], top [u]);} void push_down (int root) {if (flag [root]) {tree [root <1] = tree [root <1 | 1] = 1; ll [root <1] = ll [root <1 | 1] = rr [root <1] = rr [root <1 | 1] = ll [root]; flag [root <1] = flag [root <1 | 1] = 1; flag [root] = 0 ;}} void push_up (int root) {if (ll [root <1 | 1] = rr [root <1]) tree [root] = tree [root <<1] + tree [root <1 | 1]-1; else tree [root] = tree [root <1] + tree [root <1 | 1]; ll [root] = ll [root <1]; rr [root] = rr [root <1 | 1];} void build (int root, int l, int r) {flag [root] = 0; if (l = r) {tree [root] = 1; ll [root] = rr [root] = a [Hash [l]; return;} int mid = (l + r)> 1; build (root <1, l, mid); build (root <1 | 1, mid + 1, r); push_up (root);} void update (int root, int l, int r, int x, int y, int z) {if (l> y | r <x) return; if (x <= l & r <= y ){ Flag [root] = 1; tree [root] = 1; ll [root] = z; rr [root] = z; return;} push_down (root ); int mid = (l + r)> 1; update (root <1, l, mid, x, y, z); update (root <1 | 1, mid + 1, r, x, y, z); push_up (root);} int query (int root, int l, int r, int x, int y) {if (x <= l & r <= y) {return tree [root];} push_down (root); int sum = 0; int mid = (l + r)> 1; if (y <= mid) return query (root <1, l, mid, x, y ); else if (x> mid) return query (root <1 | 1, mid + 1, r, x, y); e Lse {int sum = query (root <1 | 1, mid + 1, r, x, y) + query (root <1, l, mid, x, y); if (ll [root <1 | 1] = rr [root <1]) sum --; return sum ;}} int query1 (int root, int l, int r, int loc) {if (l = r) {return ll [root];} push_down (root); int mid = (l + r)> 1; if (loc <= mid) return query1 (root <1, l, mid, loc); else return query1 (root <1 | 1, mid + 1, r, loc);} int main () {// freopen ("data.txt", "r", stdin); while (~ Scanf ("% d", & n, & p) {for (int I = 1; I <= n; I ++) {scanf ("% d", & a [I]) ;}init (); for (int I = 1; I <n; I ++) {int x, y; scanf ("% d", & x, & y); addedge (x, y); addedge (y, x);} z = 0, siz [0] = 0, dep [0] = 0; dfs (1, 0); init_que (1, 1); build (1, 1, z); while (p --) {char s [10]; int x, y, zz; scanf ("% s", s); if (s [0] = 'q ') {scanf ("% d", & x, & y); int f1 = top [x], f2 = top [y], sum = 0; while (f1! = F2) {if (dep [f1] <dep [f2]) {swap (f1, f2); swap (x, y);} sum + = query (1, 1, 1, z, num [f1], num [x]); if (query1 (, z, num [f1]) = query1 (, z, num [fa [f1]) {sum --;} x = fa [f1], f1 = top [x];} if (dep [x]> dep [y]) swap (x, y); sum + = query (1, 1, z, num [x], num [y]); printf ("% d \ n", sum);} else {scanf ("% d", & x, & y, & zz ); int f1 = top [x], f2 = top [y]; while (f1! = F2) {if (dep [f1] <dep [f2]) {swap (f1, f2); swap (x, y);} update (1, 1, z, num [f1], num [x], zz); x = fa [f1], f1 = top [x];} if (dep [x]> dep [y]) swap (x, y); update (1, 1, z, num [x], num [y], zz) ;}} return 0 ;}