• SPOJ QTREE4 lct


    题目链接

    这个题已经处于花式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 
    ", 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;
    }
    /*
    
    */


  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    椭圆曲线加解密
    执行计划多版本查看
    椭圆曲线算法:入门(1)
    “戏精少女”的pandas学习之路,你该这么学!No.5
    用Fabric构建应收账款融资系统的方法
    区块链的去中心化创新
    搜集统计信息
    去中心化计算
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5202198.html
Copyright © 2020-2023  润新知