Topic links
For each node, record the information for the chain on which the node is located:
LS: (the upper point of the chain) the nearest white-spot distance from the inside of the chain
RS: (bottom of chain) distance from the nearest white point within the chain
Note that all the above are real edges
Virtual Edge information is maintained with a set.
Set is maintained for each subtree that is not a chain, but this is the nearest white point distance of the subtree.
#include <stdio.h>#include <string.h>#include <set>#include <algorithm>#include <iostream>#include <vector>Template<classT>inline BOOLRD (T &ret) {CharCintSgnif(c = GetChar (), c = = EOF)return 0; while(c! ='-'&& (c<' 0 '|| C>' 9 ')) C = GetChar (); SGN = (c = ='-') ? -1:1; ret = (c = ='-') ?0: (C-' 0 '); while(c = GetChar (), C >=' 0 '&&c <=' 9 ') ret = RET *Ten+ (C-' 0 '); RET *= SGN;return 1;}Template<classT>inline voidPT (T x) {if(X <0) {Putchar('-'); x =-X; }if(x>9) PT (X/Ten);Putchar(x%Ten+' 0 ');}using namespace STD;typedef Long LongllConst intINF =1e9;Const intN =1e5+Ten;structNode *null;structnode{ multiset<int>Chain Node *fa, *ch[2];intSizeintCol, ls, RS, id, Len, Edge;//Black Col=-inf, white col=0 len is chain length BOOLRev;inline voidPut () {printf("%d son:%d,%d fa:%d len:%d (%d,%d) col:%d\n", ID, ch[0]->id, ch[1]->id, Fa->id, Len, ls, RS, col); for(AutoI:chain)printf("%d", i);puts(""); }inline voidClearint_id) {FA = ch[0] = ch[1] = null; Size =1; Rev =0; Len = Edge =0; id = _id; Chain.clear (); Chain.insert (INF); col = inf; ls = rs = inf; }inline voidPush_up () {size =1+ ch[0]->size + ch[1]->size; Len = Edge + ch[0]->len + ch[1]->len;intM0 = min (col, *chain.begin ()), ml = min (M0, ch[0]->rs + edge), Mr = Min (M0, ch[1]->LS); ls = min (ch[0]->ls, ch[0]->len + Edge + MR); rs = min (ch[1]->rs, ch[1]->len + ml); }inline voidPush_down () {if(rev) {ch[0]->flip (); ch[1]->flip (); Rev =0; } }inline voidSETC (Node *p,intd) {ch[d] = p; P->FA = This; }inline BOOLD () {returnfa->ch[1] == This; }inline BOOLIsRoot () {returnFA = = NULL | | fa->ch[0] != This&& fa->ch[1] != This; }inline voidFlip () {if( This= = NULL)return; Swap (ch[0], ch[1]); Rev ^=1; }inline voidGo () {//Start updating to this from the chain header if(!isroot ()) Fa->go (); Push_down (); }inline voidRot () {Node *f = fa, *ff = fa->fa;intc = d (), CC = Fa->d (); F->setc (Ch[!c], c); This->setc (f,!c);if(FF->CH[CC] = = f) ff->setc ( This, CC);Else This->FA = FF; F->push_up (); }inlineNode*splay () {go (); while(!isroot ()) {if(!fa->isroot ()) d () = = Fa->d ()? Fa->rot (): Rot (); Rot (); } push_up ();return This; }voidDebug (Node *x) {if(x = = null)return; X->put (); Debug (x->ch[0]); Debug (x->ch[1]); }inlinenode* access () {//access After this is a splay to the root, and this is already the root of this splay for(Node *p = This, *q = null; P! = NULL; Q = p, p = p->fa) {p->splay ();//debug (q); puts (""); Debug (P); Puts (""); if(p->ch[1]! = null) P->chain.insert (p->ch[1]->LS);if(q! = null) p->chain.erase (P->chain.find (Q->ls)); P->SETC (Q,1); P->push_up ();//debug (q); puts (""); Debug (P); Puts ("");}returnSplay (); }inlinenode* Find_root () {Node *x; for(x = Access (); X->push_down (), x->ch[0]! = NULL; x = x->ch[0]);returnX }voidMake_root () {access ()->flip (); }voidCut () {//Leave the sub-tree of this point outAccess (); ch[0]->FA = null; ch[0] = null; Push_up (); }voidCut (Node *x) {if( This= = X | | Find_root ()! = X->find_root ())return;Else{X->make_root (); Cut (); } }voidLink (Node *x) {if(Find_root () = = X->find_root ())return;Else{make_root (); FA = x; } }}; Node Pool[n], *tail; Node *node[n]; vector<int>G[n];voidDfsintUintFA) { for(intV:g[u]) {if(v = = FA)Continue; NODE[V]->FA = Node[u]; Node[v]->edge =1; DFS (v, u); Node[u]->chain.insert (NODE[V]->LS); } node[u]->push_up ();}intN, Q;voidDebug (Node *x) {if(x = = null)return; X->put (); Debug (x->ch[0]); Debug (x->ch[1]);}intMain () { while(Cin>> N) {tail = pool; NULL = tail++; Null->clear (0); Null->size =0; for(inti =1; I <= N; i++) {g[i].clear (); Node[i] = tail++; Node[i]->clear (i); } for(inti =1, u, v; I < n; i++) {rd (U); Rd (v); G[u].push_back (v); G[v].push_back (U); } DFS (1,1);//for (int i = 1; I <= n; i++) debug (Node[i]), puts ("");RD (Q); while(q--) {intU, v; RD (U); RD (v);if(U = =0) {node[v]->access ();if(Node[v]->col = = inf) Node[v]->col =0;ElseNode[v]->col = inf; Node[v]->push_up (); }Else{node[v]->access ();intans = min (*node[v]->chain.begin (), node[v]->rs);if(ans = = inf) ans =-1; PT (ANS);puts(""); }//for (int i = 1; I <= n; i++) debug (Node[i]), puts ("");} }return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Spoj QTREE5 LCT Nude questions