记录编号 170031 评测结果 AAAAAAAAA
题目名称 [TJOI 2015] 旅游 最终得分 100
用户昵称 Gravatarthomount 是否通过 通过
代码语言 C++ 运行时间 1.892 s
提交时间 2015-07-12 00:46:07 内存使用 2.63 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int read() {
	char ch = getchar();
	while (ch < '0' || ch > '9') ch = getchar();
	int ans = 0;
	while (ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0', ch = getchar();
	return ans;
}

const int ml = 2147480000;
struct point {
	int x, maxn, minn, maxd[2], plus, rev, t;
	point *s[2], * f;
	
	point(int x = 0, int t = 0): x(x), maxn(x), minn(x), plus(0), rev(0), f(0), t(t) {
		maxd[0] = maxd[1] = 0; 
		s[0] = s[1] = 0;
	}
	
	void add(int k) {
		plus += k;
		x += k;
		maxn += k;
		minn += k;
	}
	
	void push() {
		if (plus) {
			if (s[0]) s[0]->add(plus);
			if (s[1]) s[1]->add(plus);
			plus = 0;
		}
		if (rev) {
			swap(s[0], s[1]);
			if (s[0]) {
				swap(s[0]->maxd[0], s[0]->maxd[1]);
				s[0]->rev ^= 1;
			}
			if (s[1]) {
				swap(s[1]->maxd[0], s[1]->maxd[1]);
				s[1]->rev ^= 1;
			}	
			rev = 0;
		}
	}
	
	void update() {
		maxn = x, minn = x;
		maxd[0] = maxd[1] = 0;
		for (int i = 0; i < 2; i++) if (s[i]) {maxn = max(maxn, s[i]->maxn), minn = min(minn, s[i]->minn);}
		
		if (s[0]) {
			for (int i = 0; i < 2; i++) maxd[i] = max(maxd[i], s[0]->maxd[i]);
			maxd[1] = max(maxd[1], s[0]->maxn - x);
			maxd[0] = max(maxd[0], x - s[0]->minn);
		}
		
		if (s[1]) {
			for (int i = 0; i < 2; i++) maxd[i] = max(maxd[i], s[1]->maxd[i]);
			maxd[0] = max(maxd[0], s[1]->maxn - x);
			maxd[1] = max(maxd[1], x - s[1]->minn);
		}
		
		if (s[0] && s[1]) {
			maxd[0] = max(maxd[0], s[1]->maxn - s[0]->minn);
			maxd[1] = max(maxd[1], s[0]->maxn - s[1]->minn);
		}
	}
	
	bool isroot() {
		if (!f || (f->s[0] != this && f->s[1] != this)) return true; else return false;
	}
	
	int getw() {
		if (isroot()) return -1; else return (f->s[0] == this)?0:1;
	}
	
	void match(point * p, int k) {
		if (k >= 0) s[k] = p; if (p) p->f = this; update();
	}
	
	void rotate() {
		point * f1 = f; point * ff = f1->f;
		int k1 = getw(), k2 = f1->getw();
		f1->match(s[k1^1], k1);
		match(f1, 1^k1);
		if (ff) ff->match(this, k2); else f = 0;
	}
} d[50010];

typedef point * link;
link p[50010];
int tot = 0;
link make(int x, int t) {
	d[++tot] = point(x, t);
	return &d[tot];
}

link q[50010];
void splay(link p) {
	link p1 = p;
	int r = 1; q[r] = p1;
	while (!p1->isroot()) p1 = q[++r] = p1->f;
	for (int i = r; i; i--) q[i]->push();
	
	while (!p->isroot() && !p->f->isroot()) {
		if (p->getw() == p->f->getw()) p->f->rotate(); else p->rotate();
		p->rotate();
	}
	
	if (!p->isroot()) p->rotate();
}

void access(link p) {
	link q = 0;
	while (p) {
		splay(p);
		p->match(q, 1);
		q = p; p = p->f;
	}
}

void connect(link p1, link p2) {
	access(p2); splay(p2);
	p2->rev ^= 1; swap(p2->maxd[0], p2->maxd[1]);
	access(p1); splay(p1);
	p1->match(p2, -1);
}

int price[50010];

int main() {
	freopen("tjoi2015_travel.in", "r", stdin);
	freopen("tjoi2015_travel.out", "w", stdout);
	int n = read();
	for (int i = 1; i <= n; i++) {
		price[i] = read();
		p[i] = make(price[i], i);
	}
	for (int i = 1; i < n; i++) {
		int x = read(), y = read();
		connect(p[x], p[y]);
	}
	
	int m = read();
	for (int i = 1; i <= m; i++) {
		int x = read(), y = read(), rise = read();
		if (x == y) {
			printf("0\n");
			p[x]->x += rise; p[x]->update();
			access(p[x]); splay(p[x]);
			continue;
		}
		access(p[x]); splay(p[x]); 
		p[x]->rev ^= 1; 
		swap(p[x]->maxd[0], p[x]->maxd[1]);
		
		access(p[y]); splay(p[x]);
		p[x]->s[1]->f = 0; p[x]->s[1] = 0;
		splay(p[y]);
		 
		int ans = 0;
		link pp = p[y]->s[0];
		int max1 = 0, min1 = ml;
		if (pp) {ans = max(ans, pp->maxd[0]); max1 = pp->maxn; min1 = pp->minn; pp->add(rise);}
		ans = max(ans, max(max1, p[y]->x) - p[x]->x);
		ans = max(ans, p[y]->x - min(min1, p[x]->x));
		printf("%d\n", ans);
		p[x]->x += rise; p[x]->update();
		p[y]->x += rise; p[y]->update();
		p[x]->match(p[y], 1);
	}
	return 0;
}