Main topic: There are n routers, they are connected by n-1 (forming a tree). Each router has a delay value. There are two kinds of actions:
1. What is the weight of the K-large on the path between x, y two points on the query tree
2. Change the weight of x position to Y
Idea: When I think about how to do this problem, the time complexity has reached O (nlog^4n), secretly glanced at the data range ... (n,q<=80000, time limit 50s, careful to take out the calculator: 8w * log (8w) ^ 4≈56e, mind this: Treap has constant, the chain is large, the range of instability is more than 8w ... Evaluation opportunities will not be very card ... The code must be very long ... Do not write it out t ... Hey... The world. Then silently want to turn off the page. At this time, a senior standing behind me, I confided to him my difficulties. He heard it and said:
"All right, write it, I'll be over in more than 10 seconds ... ”
Seconds to go by ... It's over ... After the ... The ...
Let's just talk about ideas. Tree path, LCA or not multiply, or tree chain, with modification, can only be used to split the tree chain. K Large, is the two-point + balance tree, the second-largest is who, and then compressed the upper bound. When modifying, delete the node in each segment in the segment tree that contains the node, and then add the points that you want to change.
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 80010# Define left (POS << 1) #define RIGHT (POS << 1|1) #define SIZE (a) (A = = NULL? 0:a->size) using namespace std; struct Complex{int val,random,size,cnt; Complex *son[2],*father; Complex (int _) {val = _;random = rand (); size = CNT = 1;son[0] = son[1] = NULL;} int Compare (int x) {if (x = = val) Return-1;return x > val;} void maintain () {size = Cnt;if (son[0]! = null) size + son[0]->size;if (son[1]! = null) size + = Son[1]->size;} *root;int points,asks;int src[max];int head[max],total;int next[max << 1],aim[max << 1];int deep[MAX],son[ Max],father[max];int top[max],pos[max],temp[max],cnt; Complex *tree[max << 2];inline void Add (int x,int y), int predfs (int x,int last), void DFS (int x,int last,int _top); VO ID buildtree (int l,int r,int pos), void Modify (int l,int r,int x,int pos,int _,int __); int bisection (int x,int y,int k); int Ask (int x,int y,int k); int asK (int l,int r,int x,int y,int pos,int k), inline void Rotate (Complex *&a,bool dir); void Insert (Complex *&a,int x); v OID Delete (Complex *&a,int x); int GetRank (Complex *a,int k); int main () {cin >> points >> asks;for (int i = 1 ; I <= points; ++i) scanf ("%d", &src[i]), for (int x,y,i = 1;i < points; ++i) {scanf ("%d%d", &x,&y); Add (x, y), add (y,x);} Predfs (1,0);D FS (1,0,1); Buildtree (1,cnt,1); for (int flag,x,y,i = 1;i <= asks; ++i) {scanf ("%d%d%d", &flag,&x,&y); if (!flag) { Modify (1,cnt,pos[x],1,y,src[x]); src[x] = y;} else {int temp = bisection (x,y,flag)-1;if (temp = =-1) puts ("Invalid request!"); elseprintf ("%d\n", temp);}} return 0;} inline void Add (int x,int y) {next[++total] = head[x];aim[total] = y;head[x] = total;} int Predfs (int x,int last) {father[x] = last;deep[x] = Deep[last] + 1;int max_size = 0,re = 1;for (int i = Head[x];i;i = Nex T[i]) {if (aim[i] = = last) Continue;int temp = Predfs (aim[i],x), Re + = temp;if (Temp > max_size) son[x] = Aim[i],max_size =temp;} return re;} void Dfs (int x,int last,int _top) {temp[++cnt] = Src[x];p os[x] = cnt;top[x] = _top;if (son[x]) DFS (son[x],x,_top); for (int i = Head[x];i;i = Next[i]) {if (aim[i] = = Last | | aim[i] = = Son[x]) Continue;dfs (Aim[i],x,aim[i]);}} void Buildtree (int l,int r,int POS) {for (int i = L;i <= r; ++i) Insert (Tree[pos],temp[i]), if (L = = r) return; int mid = (l + R) >> 1; Buildtree (L,mid,left); Buildtree (mid + 1,r,right);} void Modify (int l,int r,int x,int pos,int _,int __) {Delete (tree[pos],__); Insert (tree[pos],_); if (L = = r) return; int mid = ( L + R) >> 1;if (x <= mid) Modify (l,mid,x,left,_,__); Elsemodify (mid + 1,r,x,right,_,__);} int bisection (int x,int y,int k) {int L = 0,r = static_cast<int> (1e8), ans = 0;while (l <= r) {int mid = (L + R) ;> 1;if (Ask (x,y,mid) >= k) L = mid + 1;elser = Mid-1,ans = mid;} return ans;} int Ask (int x,int y,int k) {int re = 0;while (top[x]! = Top[y]) {if (Deep[top[x]] < Deep[top[y]]) swap (x, y); re + = Ask (1,cnt , pos[top[x]],pos[x],1,k); x = FatheR[TOP[X]];} if (Deep[x] > Deep[y]) swap (x, y), re + = Ask (1,cnt,pos[x],pos[y],1,k); return re;} int Ask (int l,int r,int x,int y,int pos,int k) {if (L = = x && r = = y) return GetRank (tree[pos],k); int mid = (L + R) & Gt;> 1;if (y <= mid) return Ask (L,mid,x,y,left,k), else if (X > Mid) return ask (mid + 1,r,x,y,right,k); int left = Ask ( L,MID,X,MID,LEFT,K), int right = Ask (mid + 1,r,mid + 1,y,right,k), return left + right;} inline void Rotate (Complex *&a,bool dir) {Complex *k = A->son[!dir];a->son[!dir] = k->son[dir];k->son[ DIR] = A;a->maintain (), K->maintain (); a = k;} void Insert (Complex *&a,int x) {if (a = = NULL) {a = new Complex (x); return;} int dir = a->compare (x); if (dir = =-1) a->cnt++;else {Insert (a->son[dir],x); if (A->son[dir]->random > A->random) Rotate (A,!dir);} A->maintain ();} void Delete (Complex *&a,int x) {int dir = a->compare (x), if (dir! =-1) Delete (a->son[dir],x); else {if (a->cnt & Gt 1)--a->cnt;else {if (a->son[0] = = NULL) A= A->son[1];else if (a->son[1] = = NULL) A = A->son[0];else {bool _ = (A->son[0]->random > A->son[1]-> , random); Rotate (a,_);D elete (a->son[_],x);}} if (A! = NULL) A->maintain ();} int GetRank (Complex *a,int k) {if (a = = NULL) return 0;if (K > A->val) return GetRank (a->son[1],k); if (k = = A->val) return a->cnt + GetRank (a->son[1],k), return SIZE (a->son[1]) + a->cnt + getrank (a->son[0],k);}
Bzoj 1146 CTSC 2008 Network Management Web tree chain split + dichotomy answer + balance tree