SPOJ QTREE4 lct

来源:互联网 发布:搜衣服的软件 编辑:程序博客网 时间:2024/05/29 10:08

题目链接

这个题已经处于花式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() {//从链头开始更新到thisif (!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;}/**/


0 0
原创粉丝点击