题目链接
这个题已经处于花式tle了,改版后的spoj更慢了。。
tle的话就多交几把。。。
#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 * 10 + (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); putchar(x % 10 + '0'); } typedef long long ll; typedef pair<int, int> pii; const int N = 200000 + 10; const int inf = 1e9; struct Node *null; inline int First(multiset<int>&x) {//返回x中最大的数 return *x.rbegin(); } inline int Second(multiset<int>&x) {//返回x中次大的数 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]->id, fa->id, col); // cout << "path: ";for (auto i : path)cout << i << " ";puts(""); // cout << "chain:";for (auto i : chain)cout << i << " ";puts(""); } 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(chain)); int L = max(_chain, ch[0]->rs + len);//从(虚边 or 左子树)的白点到this的最远距离 int R = max(_chain, ch[1]->ls);//从(虚边 or 右子树)的白点到this的最远距离 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; } inline void go() {//从链头开始更新到this if (!isroot())fa->go(); push_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); if (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后this就是到根的一条splay,并且this已经是这个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() {//把这个点的子树脱离出去 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(); debug(x->ch[0]); debug(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]->fa = 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]->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 have disappeared."); else pt(ans), puts(""); } // for (int i = 1; i <= n; i++)debug(node[i]), puts(""); } } return 0; } /* */