10pts 求助
查看原帖
10pts 求助
754311
zhangjiting楼主2023/12/22 22:44
#include<bits/stdc++.h>
#define INT_MAX ((int)1000000100)
#define INT_MIN ((int)-1000000100)
using namespace std;
const int N=5e4+5;
int cnt,n,m,s;
int top[N],son[N],dep[N],siz[N],fa[N],dfn[N],a[N],num[N],tot;
int to[2*N],nxt[2*N],head[2*N];
void add(int x,int y){
	to[++tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
void dfs1(int x,int f){
	siz[x]=1;dep[x]=dep[f]+1;fa[x]=f;
	int mx=INT_MIN;
  	for(int i=head[x];i;i=nxt[i]){
  		int y=to[i];
  		if(y==f) continue;
  		dfs1(y,x);
  		siz[x]+=siz[y];
  		if(siz[y]>mx)mx=siz[y],son[x]=y;
	}
}
void dfs2(int x,int hd){
	top[x]=hd;
	dfn[x]=++cnt;
	a[cnt]=num[x];
	if(son[x]) dfs2(son[x],hd);
	for(int i=head[x];i;i=nxt[i]){
		int y=to[i];
		if(y!=son[x]&&y!=fa[x]) dfs2(y,y);
	}
}
// 线段树开始
struct node{
	int ma,mi,lma,rma,tag;
}tree[N*4];
void pushup(int p){
	tree[p].ma=max(tree[p*2].ma,tree[p*2+1].ma);
	tree[p].mi=min(tree[p*2].mi,tree[p*2+1].mi);
	tree[p].lma=max(tree[p*2+1].ma-tree[p*2].mi,max(tree[p*2].lma,tree[p*2+1].lma));
	tree[p].rma=max(tree[p*2].ma-tree[p*2+1].mi,max(tree[p*2].rma,tree[p*2+1].rma));
}
void pushdown(int p){
	int k=tree[p].tag;
	tree[p].tag=0;
	tree[p*2].ma+=k;
	tree[p*2].mi+=k;
	tree[p*2].tag+=k;
	tree[p*2+1].ma+=k;
	tree[p*2+1].mi+=k;
	tree[p*2+1].tag+=k;
}
void build(int p,int l,int r){
	if(l==r){
		tree[p].ma=a[l];
		tree[p].mi=a[r];
		return;
	}
	int mid=l+r>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	pushup(p);
}
void change(int p,int lt,int rt,int l,int r,int k){
	if(lt>=l&&rt<=r){
		tree[p].ma+=k;
		tree[p].mi+=k;
		tree[p].tag+=k;
		return;
	}
	if(tree[p].tag!=0&&l!=r)pushdown(p);
	int mid=lt+rt>>1;
	if(mid>=l) change(p*2,lt,mid,l,r,k);
	if(mid<r) change(p*2+1,mid+1,rt,l,r,k);
	pushup(p);
}
node ask(int p,int lt,int rt,int l,int r){
	if(lt>=l&&rt<=r) return tree[p];
	if(tree[p].tag!=0&&l!=r)pushdown(p);
	int mid=lt+rt>>1;
	if(mid>=r) return ask(p*2,lt,mid,l,r);
	else if(mid<l) return ask(p*2+1,mid+1,rt,l,r);
	else{
		node lans=ask(p*2,lt,mid,l,r);
		node rans=ask(p*2+1,mid+1,rt,l,r);
		node ans;
		ans.ma=max(lans.ma,rans.ma);
		ans.mi=min(lans.mi,rans.mi);
		ans.lma=max(max(lans.lma,rans.lma),rans.ma-lans.mi);
		ans.rma=max(max(lans.rma,rans.rma),lans.ma-rans.mi);
		return ans;
	}
}
// 线段树结束
int askans(int x,int y){
	node l,r;
	l.lma=l.rma=0,l.ma=INT_MIN,l.mi=INT_MAX;r=l;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]){
			node ans=ask(1,1,n,dfn[top[y]],dfn[y]);
			r.lma=max(max(ans.lma,r.lma),r.ma-ans.mi);
			r.rma=max(max(ans.rma,r.rma),ans.ma-r.mi);
			r.ma=max(r.ma,ans.ma);
			r.mi=min(r.mi,ans.mi);
			y=fa[top[y]];
		}
		else{
			node ans=ask(1,1,n,dfn[top[x]],dfn[x]);
			l.lma=max(max(ans.lma,l.lma),l.ma-ans.mi);
			l.rma=max(max(ans.rma,l.rma),ans.ma-l.mi);
			l.ma=max(l.ma,ans.ma);
			l.mi=min(l.mi,ans.mi);
			x=fa[top[x]];
		}
	}
	if(dep[x]<dep[y]){
		node ans=ask(1,1,n,dfn[x],dfn[y]);
		r.lma=max(max(ans.lma,r.lma),r.ma-ans.mi);
		r.rma=max(max(ans.rma,r.rma),ans.ma-r.mi);
		r.ma=max(r.ma,ans.ma);
		r.mi=min(r.mi,ans.mi);
	}
	else{
		node ans=ask(1,1,n,dfn[y],dfn[x]);
		l.lma=max(max(ans.lma,l.lma),l.ma-ans.mi);
		l.rma=max(max(ans.rma,l.rma),ans.ma-l.mi);
		l.ma=max(l.ma,ans.ma);
		l.mi=min(l.mi,ans.mi);
	}
	return max(max(l.rma,r.lma),r.ma-l.mi);
}
void upt(int x,int y,int k){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		change(1,1,n,dfn[top[x]],dfn[x],k);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	change(1,1,n,dfn[x],dfn[y],k);
}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>num[i];
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		add(u,v);
		add(v,u);
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,n);
	cin>>m;
	for(int _=1;_<=m;_++){
		int a,b,v;
		cin>>a>>b>>v;
		cout<<askans(a,b)<<endl;
		upt(a,b,v);
	}
	return 0;
}
2023/12/22 22:44
加载中...