【SPOJ-QTREE】Query on a tree【Link-Cut Tree】

一开始写成成员函数,结果TLETLETLE了...


#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 25005, inf = 0x3f3f3f3f;

int n, st[maxn], head[maxn], cnt;

inline int iread() {
	int f = 1, x = 0; char ch = getchar();
	for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return f * x;
}

struct _edge {
	int v, next;
} g[maxn << 1];

inline void add(int u, int v) {
	g[cnt] = (_edge) {v, head[u]};
	head[u] = cnt++;
}
	
int son[maxn][2], fa[maxn], w[maxn], __max[maxn];
bool rev[maxn];

inline bool isroot(int x) {
	return son[fa[x]][0] != x && son[fa[x]][1] != x;
}

inline void pushup(int x) {
	__max[x] = max(w[x], max(__max[son[x][0]], __max[son[x][1]]));
}

inline void pushdown(int x) {
	if(rev[x]) {
		rev[son[x][0]] ^= 1; rev[son[x][1]] ^= 1;
		swap(son[x][0], son[x][1]);
		rev[x] = 0;
	}
}

inline void maintain(int x) {
	int top = 0; st[++top] = x;
	for(; !isroot(x); x = fa[x]) st[++top] = fa[x];
	while(top) pushdown(st[top--]);
}

inline void rotate(int x) {
	int y = fa[x], z = fa[y], type = son[y][1] == x;
	fa[son[y][type] = son[x][!type]] = y;
	fa[x] = z;
	if(!isroot(y)) son[z][son[z][1] == y] = x;
	fa[son[x][!type] = y] = x;
	pushup(y); pushup(x);
}

inline void splay(int x) {
	maintain(x);
	while(!isroot(x)) {
		int y = fa[x], z = fa[y];
		if(isroot(y)) rotate(x);
		else if(son[z][0] == y ^ son[y][0] == x) rotate(x), rotate(x);
		else rotate(y), rotate(x);
	}
}

inline void access(int x) {
	for(int y = 0; x; y = x, x = fa[x]) {
		splay(x);
		son[x][1] = y;
		pushup(x);
	}
}

inline void makeroot(int x) {
	access(x); splay(x); rev[x] ^= 1;
}

inline void change(int x, int c) {
	splay(x); w[x] = c; pushup(x);
}

inline int query(int x, int y) {
	makeroot(x); access(y); splay(y); 
	return __max[y];
}

int val[maxn];

void dfs(int x, int f) {
	fa[x] = f;
	w[x] = __max[x] = val[x];
	for(int i = head[x]; ~i; i = g[i].next) if(g[i].v ^ f) dfs(g[i].v, x);
}

int main() {
	int T = iread();

	while(T--) {
		n = iread();

		for(int i = 0; i < maxn; i++)
			son[i][0] = son[i][1] = fa[i] = rev[i] = 0, head[i] = -1, w[i] = __max[i] = val[i] = -inf;
		cnt = 0;

		for(int i = 1; i < n; i++) {
			int x = iread(), y = iread(), c = iread();
			add(x, i + n); add(i + n, x); add(y, i + n); add(i + n, y);
			val[i + n] = c;
		}
		dfs(1, 0);

		while(1) {
			char ch = getchar(); for(; ch != 'Q' && ch != 'C' && ch != 'D'; ch = getchar());
			if(ch == 'D') break;

			int x = iread(), y = iread();
			if(ch == 'C') change(x + n, y);
			else if(ch == 'Q') printf("%d\n", query(x, y));
		}
	}
	return 0;
}


你可能感兴趣的:(tree,Link-Cut)