Topic links
The problem is already in the fancy tle, and the revised SPOJ is slower.
If you're in tle, you'll have to pay a few more ...
#include <iostream> #include <fstream> #include <string> #include <time.h> #include <vector > #include <map> #include <queue> #include <algorithm> #include <stack> #include <cstring > #include <cmath> #include <set> #include <vector>using namespace std;template <class t> inline BOOL Rd (T &ret) {char c; int sgn;if (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 * + (C-' 0 '); ret *= Sgn;return 1;} Template <class t>inline void pt (T x) {if (x < 0) {Putchar ('-'); x =-X;} if (x > 9) pt (X/10);p Utchar (x% 10 + ' 0 ');} typedef long Long Ll;typedef pair<int, int> pii;const int N = 200000 + 10;const int inf = 1e9;struct Node *null;inli NE int First (MULTISET<INT>&X) {//returns the largest number in X return *x.rbegin ();} inline int Second (multiset<INT>&X) {//returns x the number of multiset<int>::reverse_iterator it = X.rbegin (); it++; return *it;} struct Node {node *fa, *ch[2];int size;multiset<int>path, Chain;int ls, RS, ms;int col, Len, id;bool rev;inline void Put () {printf ("%d siz:%d len:%d (%d,%d,%d) son{%d,%d} fa:%d col:%d \ n", id, size, len, ls, RS, MS, Ch[0]->id, CH[1]-&G T;id, Fa->id, col)//cout << "path:"; for (auto I:path) cout << i << "";p UTS ("");//cout << "C Hain: "for (auto I:chain) cout << i <<" ";p UTS (" ");} inline void Clear (int _col, int _id) {FA = ch[0] = ch[1] = Null;rev = 0;id = _id;col = _col;size = Len = 0;ls = rs = ms = -inf;path.clear (); Chain.clear (); Chain.insert (-inf); Chain.insert (-inf); Path.insert (-inf);} inline void push_up () {if (this = null) Return;size = len + ch[0]->size + ch[1]->size;int _chain = max (col, first (ch Ain)), int L = max (_chain, Ch[0]->rs + len),//from the white point of the (virtual Edge or Zuozi) to the furthest distance int R = max (_chain, ch[1]->ls);//from (virtual edge or right subtree) The white point to this is the mostLong Distance ls = max (ch[0]->ls, ch[0]->size + len + R), rs = max (Ch[1]->rs, Ch[1]->size + L), MS = MAX (Ch[0]->rs + len + R, L + ch[1]->ls), MS = Max (MS, Max (CH[0]->MS, Ch[1]->ms)), MS = MAX (MS, first (path)), MS = MAX (MS, first (chain) + Second (chain)); if (col = = 0) ms = MAX (max (MS, first (chain)), 0);} inline void Push_down () {if (rev.) {ch[0]->flip (); Ch[1]->flip (); rev = 0;}} inline void SetC (Node *p, int d) {Ch[d] = P;p->fa = this;} inline bool D () {return fa->ch[1] = = this;} inline bool IsRoot () {return FA = = NULL | | fa->ch[0]! = this && fa->ch[1]! = this; inline void Flip () {if (this = null) Return;swap (ch[0], ch[1]); rev ^= 1;} The inline void Go () {//is updated from the chain header to Thisif (!isroot ()) Fa->go ();p ush_down ();} inline void rot () {Node *f = fa, *ff = fa->fa;int C = d (), CC = Fa->d (), F->setc (Ch[!c], C), This->setc (f,!c); F (ff->ch[cc] = = f) ff->setc (this, cc); else This->fa = Ff;f->push_up ();} Inline Node*splay () {//go (); while (!isroot ()) {if (!fa-> IsRoot ()) d () = = Fa->d ()? Fa->rot (): Rot (); Rot ();} Push_up (); return this;} Inline node* access () {//access After this is a splay to the root, and this is already the root of the splay for (Node *p = this, *q = NULL; P! = null; q = p, p = P->FA) {P->splay (), if (p->ch[1]! = null) {P->chain.insert (p->ch[1]->ls);p->path.insert (p-> CH[1]->MS);} if (q! = null) {p->chain.erase (P->chain.find (q->ls));p->path.erase (P->path.find (Q->ms));} P->SETC (q, 1);p->push_up ();} return splay ();} Inline node* find_root () {Node *x;for (x = Access (); X->push_down (), x->ch[0]! = null; x = x->ch[0]); return x;} void Make_root () {access ()->flip ();} void Cut () {//Leave the sub-tree of this point out of access (); Ch[0]->fa = null;ch[0] = Null;push_up ();} void Cut (Node *x) {if (this = = X | | find_root ()! = X->find_root ()) Return;else {x->make_root (); Cut ();}} void link (Node *x) {if (find_root () = = X->find_root ()) Return;else {make_root (); fa = x;}}}; void Debug (Node *x) {if (x = = null) return;x->put ();d ebug (x->ch[0]);d Ebug (x->ch[1]);} Node Pool[n], *tail; Node *node[n];int N, q;struct Edge {int to, next, dis;} Edge[n<<1];int Head[n], edgenum;inline void Add (int u, int v, int dis) {Edge E = {V, head[u], dis};edge[edgenum] = E;head[u] = edgenum++;} void Dfs (int u, int fa) {for (int i = head[u]; ~i; i = edge[i].next) {int v = edge[i].to;if (v = = FA) continue;node[v]->f A = Node[u];node[v]->len = Edge[i].dis;dfs (V, u); Node[u]->path.insert (NODE[V]->MS);node[u]-> Chain.insert (NODE[V]->LS);} Node[u]->push_up ();} int main () {while (CIN >> n) {tail = Pool;null = Tail++;null->clear (-inf, 0); edgenum = 0;for (int i = 1; I <= N i++) {Head[i] = -1;node[i] = tail++;node[i]->clear (0, i);} for (int i = 1, u, V, D; i < n; i++) {rd (U); Rd (v); Rd (d); Add (U, V, d); add (V, U, d);} DFS (1, 1); Rd (Q); Char str[5]; int u;int ans = node[1]->ms;while (q--) {scanf ("%s", str), if (str[0] = = ' C ') {rd (U); node[u]->access (); if (NODE[U]-&G T;col = = 0) Node[u]->col =-inf;else Node[u]->coL = 0;node[u]->push_up (); ans = node[u]->ms;} else {if (ans < 0) puts ("They has disappeared."); Else 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 QTREE4 LCT