记录编号 162537 评测结果 AAAAAAAAA
题目名称 [TJOI 2015] 旅游 最终得分 100
用户昵称 GravatarAsm.Def 是否通过 通过
代码语言 C++ 运行时间 0.923 s
提交时间 2015-05-17 17:34:36 内存使用 7.22 MiB
显示代码纯文本
/***********************************************************************/
/**********************By Asm.Def-Wu Jiaxin*****************************/
/***********************************************************************/
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <algorithm>
using namespace std;
#define SetFile(x) ( freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout) );
//#define UseFREAD
#ifdef UseFREAD
#define getc() *(file_ptr++)
#define FreadLenth 5000000
char CHARPOOL[FreadLenth], *file_ptr = CHARPOOL;
#else
#define getc() getchar() 
#endif
#ifdef DEBUG
#include <ctime>
#endif
template<class T>inline void getd(T &x){
	char ch = getc();bool neg = false;
	while(!isdigit(ch) && ch != '-')ch = getc();
	if(ch == '-')ch = getc(), neg = true;
	x = ch - '0';
	while(isdigit(ch = getc()))x = x * 10 - '0' + ch;
	if(neg)x = -x;
}
/***********************************************************************/
const int maxn = 50002, INF = 0x3f3f3f3f;

int N;
int top[maxn], dep[maxn], id[maxn], seq[maxn], val[maxn], size[maxn], p[maxn], son[maxn];

#include <vector>
vector<int> adj[maxn];

struct Data{
	int md, rmd, Min, Max;
	inline void init(){md = rmd = Max = 0, Min = INF;}
	inline void init(int v){md = rmd = 0, Min = Max = v;}
};
inline Data operator + (const Data &a, const Data &b){
	int md, rmd, Min, Max;
	Min = min(a.Min, b.Min);
	Max = max(a.Max, b.Max);
	md = max(b.Max - a.Min, max(a.md, b.md));
	rmd = max(a.Max - b.Min, max(a.rmd, b.rmd));
	return (Data){md, rmd, Min, Max};
}
inline Data rev(const Data &x){
	Data ans = x;
	swap(ans.md, ans.rmd);
	return ans;
}
inline void operator += (Data &a, int d){a.Min += d, a.Max += d;}

struct SegT{
	Data dt;
	int L, R, mid, tag;
	SegT *ls, *rs;
	inline void push(){
		if(ls)ls->tag += tag, rs->tag += tag, ls->dt += tag, rs->dt += tag;
		tag = 0;
	}
	void init(int, int);
	void Add(int l, int r, int d){
		if(tag)push();
		if(L == l && R == r){
			dt += d;
			tag += d;
			return;
		}
		if(r <= mid)ls->Add(l, r, d);
		else if(l >= mid)rs->Add(l, r, d);
		else ls->Add(l, mid, d), rs->Add(mid, r, d);
		dt = ls->dt + rs->dt;
	}
	Data Query(int l, int r){
		if(tag)push();
		if(L == l && R == r)return dt;
		if(r <= mid)return ls->Query(l, r);
		if(l >= mid)return rs->Query(l, r);
		return ls->Query(l, mid) + rs->Query(mid, r);
	}
}T[maxn * 3], *iter = T + maxn - 1;

void SegT::init(int l, int r){
	L = l, R = r;mid = (l + r) >> 1;
	if(l == mid){
		dt.init(seq[l]);
		return;
	}
	ls = ++iter;ls->init(l, mid);
	rs = ++iter;rs->init(mid, r);
	dt = ls->dt + rs->dt;
}

void dfs(int cur){
	vector<int>::iterator it;
	int to, maxs = 0, hs;
	size[cur] = 1;
	for(it = adj[cur].begin();it != adj[cur].end();++it)if((to = *it) != p[cur]){
		dep[to] = dep[cur] + 1;
		p[to] = cur;
		dfs(to);
		if(size[to] > maxs)maxs = size[to], hs = to;
		size[cur] += size[to];
	}
	if(maxs)son[cur] = hs;
}

void build(int cur, int ind){
	vector<int>::iterator it;
	int to, s;
	seq[id[cur] = ind++] = val[cur];
	if((s = son[cur])){
		top[s] = top[cur];
		build(s, ind);
	}
	else T[top[cur]].init(0, ind);

	for(it = adj[cur].begin();it != adj[cur].end();++it)if((to = *it) != p[cur] && to != s){
		ind = 0;
		top[to] = to;
		build(to, 0);
	}
}

inline void init(){
	getd(N);
	int i, u, v;
	for(i = 1;i <= N;++i)getd(val[i]);
	for(i = 1;i < N;++i){
		getd(u), getd(v);
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	dep[1] = 1;dfs(1);
	top[1] = 1;build(1, 0);
}

inline void work(){
	int Q, u, v, a, b, d;getd(Q);
	Data s, t, mid;
	while(Q--){
		getd(u), getd(v), getd(d);
		s.init(), t = s;
		a = top[u], b = top[v];
		while(a != b){
			if(dep[a] <= dep[b]){
				T[b].Add(id[b], id[v]+1, d);
				t = T[b].Query(id[b], id[v]+1) + t;
				v = p[b];b = top[v];
			}
			else{
				T[a].Add(id[a], id[u]+1, d);
				s = T[a].Query(id[a], id[u]+1) + s;
				u = p[a];a = top[u];
			}
		}
		if(dep[u] <= dep[v])T[a].Add(id[u], id[v]+1, d), mid = T[a].Query(id[u], id[v] + 1);
		else T[a].Add(id[v], id[u]+1, d), mid = rev(T[a].Query(id[v], id[u] + 1));
		s = (rev(s) + mid + t);
		printf("%d\n", s.md);
	}
}

int main(){

#ifdef DEBUG
	freopen("test.txt", "r", stdin);
#elif !defined ONLINE_JUDGE
	SetFile(tjoi2015_travel);
#endif

#ifdef UseFREAD
	fread(file_ptr, 1, FreadLenth, stdin);
#endif

	init();
	work();

#ifdef DEBUG
	printf("\n%.3lf sec \n", (double)clock() / CLOCKS_PER_SEC);
#endif
	return 0;
}