记录编号 162636 评测结果 AAAAAAAAA
题目名称 [TJOI 2015] 旅游 最终得分 100
用户昵称 Gravatar天一阁 是否通过 通过
代码语言 C++ 运行时间 1.899 s
提交时间 2015-05-18 13:59:03 内存使用 5.44 MiB
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <algorithm>

#define l(x) ch[x][0]
#define r(x) ch[x][1]
#define mv(x) tree[x].mv
#define rmv(x) tree[x].rmv
#define maxv(x) tree[x].maxv
#define minv(x) tree[x].minv
#define addv(x) addv[x]
#define N 50010
#define MP(x,y) make_pair(x,y)
#define fir first
#define sec second
#define INF 0x3f3f3f3f

using namespace std;

void file(){
	freopen("tjoi2015_travel.in","r",stdin);
	freopen("tjoi2015_travel.out","w",stdout);
}

struct node{
	int mv,maxv,minv;
	int rmv;
	void init(){
		rmv=mv=0;
		maxv=0;
		minv=INF;
	}
}tree[N<<1];

node reverse(node x){
	swap(x.rmv,x.mv);
	return x;
}

node operator+(const node &a,const node &b){
	node c;
	c.rmv=max(a.rmv,b.rmv);
	c.rmv=max(c.rmv,a.maxv-b.minv);
	c.mv=max(a.mv,b.mv);
	c.mv=max(c.mv,b.maxv-a.minv);
	c.minv=min(a.minv,b.minv);
	c.maxv=max(a.maxv,b.maxv);
	return c;
}

int ch[N<<1][2],tot,tot_n,pos[N],addv[N<<1];

void update(int x){
	if(!l(x)) return;
	tree[x]=tree[l(x)]+tree[r(x)];
}

int build(int src[],int l,int r){
	int x=++tot;
	addv(x)=0;
	if(l==r){
		maxv(x)=minv(x)=src[pos[l]];
		mv(x)=rmv(x)=0;
		return x;
	}
	int mid=(l+r)>>1;
	l(x)=build(src,l,mid);
	r(x)=build(src,mid+1,r);
	update(x);
	return x;
}

void push(int x){
	if(!addv(x)||!l(x)) return;
	addv(l(x))+=addv(x);
	maxv(l(x))+=addv(x);
	minv(l(x))+=addv(x);
	addv(r(x))+=addv(x);
	maxv(r(x))+=addv(x);
	minv(r(x))+=addv(x);
	addv(x)=0;
}

node ask(int o,int l,int r,int ql,int qr){
	push(o);
	if(ql<=l&&r<=qr){
		return tree[o];
	}
	int mid=(l+r)>>1;
	if(ql<=mid&&mid<qr){
		node lc=ask(l(o),l,mid,ql,qr);
		node rc=ask(r(o),mid+1,r,ql,qr);
		update(o);
		return lc+rc;
	}
	if(ql<=mid){
		node lc=ask(l(o),l,mid,ql,qr);
		update(o);
		return lc;
	}
	if(mid<qr){
		node rc=ask(r(o),mid+1,r,ql,qr);
		update(o);
		return rc;
	}
}

void addin(int o,int l,int r,int ql,int qr,int qv){
	push(o);
	if(ql<=l&&r<=qr){
		addv(o)+=qv;
		maxv(o)+=qv;
		minv(o)+=qv;
		return;
	}
	int mid=(l+r)>>1;
	if(ql<=mid) addin(l(o),l,mid,ql,qr,qv);
	if(mid<qr) addin(r(o),mid+1,r,ql,qr,qv);
	update(o);
}

struct edge{
	int x,to;
}E[N<<1];

int n,m,top[N],fa[N],L[N],d[N],g[N],totE,siz[N],h[N],tott,a[N];

void ade(int x,int y){
	E[++totE]=(edge){y,g[x]}; g[x]=totE;
}

#define p E[i].x

void dfs1(int x){
	siz[x]=1;
	for(int i=g[x];i;i=E[i].to)
		if(p!=fa[x]){
			d[p]=d[x]+1;
			fa[p]=x;
			dfs1(p);
			siz[x]+=siz[p];
			if(siz[p]>siz[h[x]]) h[x]=p;
		}
}

void dfs2(int x,int tp){
	top[x]=tp; L[x]=++tott; pos[tott]=x;
	if(h[x]) dfs2(h[x],tp);
	for(int i=g[x];i;i=E[i].to)
		if(p!=fa[x]&&p!=h[x]) dfs2(p,p);
}

int com_ask(int u,int v){
	int f1=top[u],f2=top[v];
	tot_n=0;
	node ls,rs;
	ls.init(); rs.init();
	while(f1!=f2){
		if(d[f1]>=d[f2]){
			ls=ask(1,1,n,L[f1],L[u])+ls;
			u=fa[f1],f1=top[u];
		}
		else{
			rs=ask(1,1,n,L[f2],L[v])+rs;
			v=fa[f2],f2=top[v];
		}
	}
	ls=reverse(ls);
	if(d[u]<=d[v])	ls=ls+ask(1,1,n,L[u],L[v]);
	else rs=reverse(ask(1,1,n,L[v],L[u]))+rs;
	node ans=ls+rs;
	return ans.mv;
}

void com_add(int u,int v,int w){
	int f1=top[u],f2=top[v];
	while(f1!=f2){
		if(d[f1]<d[f2]) swap(f1,f2),swap(u,v);
		addin(1,1,n,L[f1],L[u],w);
		u=fa[f1]; f1=top[u];
	}
	if(L[u]>L[v]) swap(u,v);
	addin(1,1,n,L[u],L[v],w);
}

int main(){
	file();
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<n;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		ade(x,y); ade(y,x);
	}
	d[1]=1;
	dfs1(1); dfs2(1,1);
	build(a,1,n);
	scanf("%d",&m);
	for(int i=1;i<=m;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		com_add(x,y,z);
		printf("%d\n",com_ask(x,y));
	}
	return 0;
}