样例全过,但只有10分
查看原帖
样例全过,但只有10分
1049442
OIerror楼主2024/8/28 20:35
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int n,m,r,p;
vector<int>g[100001];
struct segment
{
	int _begin,_end;
};
vector<segment>rev[2];
int a[100001];
int dfn[100001],rdfn[100001],dep[100001],father[100001],wc[100001],sz[100001],top[100001],vistime=0;
int lw[400001],rw[400001],maxw[400001],minw[400001],lzy[400001];
void dfs1(int u,int f)
{
	father[u]=f;
	sz[u]=1;
	dep[u]=dep[f]+1;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v!=f)
		{
			dfs1(v,u);
			sz[u]+=sz[v];
			if(sz[v]>sz[wc[u]])
			{
				wc[u]=v;
			}
		}
	}
}
void dfs2(int u,int Top)
{
	vistime++;
	dfn[u]=vistime;
	rdfn[vistime]=u;
	top[u]=Top;
	if(wc[u]!=0)
	{
		dfs2(wc[u],Top);
	}
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(v!=father[u]&&v!=wc[u])
		{
			dfs2(v,v);
		}
	}
}
void split(int u,int v)
{
	rev[0].clear();
	rev[1].clear();
	int x=0,y=1;
	while(top[u]!=top[v])
	{
		if(dep[top[u]]<dep[top[v]])
		{
			swap(u,v);
			swap(x,y);
		}
		rev[x].push_back((segment){dfn[top[u]],dfn[u]});
		u=father[top[u]];
	}
	if(dep[u]>dep[v])
	{
		swap(u,v);
	}
	rev[x].push_back((segment){dfn[u],dfn[v]});
	reverse(rev[1].begin(),rev[1].end());
//	for(int i=0;i<rev[0].size();i++)
//	{
//		printf("%d %d\n",rev[0][i]._begin,rev[0][i]._end);
//	}
//	for(int i=0;i<rev[1].size();i++)
//	{
//		printf("%d %d\n",rev[1][i]._begin,rev[1][i]._end);	
//	}
}
void pushup(int u)
{
	lw[u]=max(max(lw[u*2],lw[u*2+1]),maxw[u*2]-minw[u*2+1]);
	rw[u]=max(max(rw[u*2],rw[u*2+1]),maxw[u*2+1]-minw[u*2]);
	maxw[u]=max(maxw[u*2],maxw[u*2+1]);
	minw[u]=min(minw[u*2],minw[u*2+1]);
}
void maketag(int u,int x)
{
	lzy[u]+=x;
	maxw[u]+=x;
	minw[u]+=x;
}
void pushdown(int u,int l,int r)
{
	int mid=(l+r)/2;
	maketag(u*2,lzy[u]);
	maketag(u*2+1,lzy[u]);
	lzy[u]=0;
}
bool inrange(int l,int r,int L,int R)
{
	return (L<=l)&&(r<=R);
}
bool outrange(int l,int r,int L,int R)
{
	return (r<L)||(R<l);
}
void build(int u,int l,int r)
{
	if(l==r)
	{
		lw[u]=0;
		rw[u]=0;
		maxw[u]=minw[u]=a[rdfn[l]];
//		printf("%d %d %d %d %d\n",u,lw[u],rw[u],maxw[u],minw[u]);
		return;
	}
	int mid=(l+r)/2;
	build(u*2,l,mid);
	build(u*2+1,mid+1,r);
	pushup(u);
//	printf("%d %d %d %d %d\n",u,lw[u],rw[u],maxw[u],minw[u]);
}
void update(int u,int l,int r,int L,int R,int v)
{
	if(inrange(l,r,L,R))
	{
		maketag(u,v);
	}
	else if(!outrange(l,r,L,R))
	{
		int mid=(l+r)/2;
		pushdown(u,l,r);
		update(u*2,l,mid,L,R,v);
		update(u*2+1,mid+1,r,L,R,v);
		pushup(u);
	}
}
struct node
{
	int lw,rw,maxw,minw;
};
node ask(int u,int l,int r,int L,int R)
{
	if(inrange(l,r,L,R))
	{
		return (node){lw[u],rw[u],maxw[u],minw[u]};
	}
	else if(!outrange(l,r,L,R))
	{
		int mid=(l+r)/2;
		pushdown(u,l,r);
		node a=ask(u*2,l,mid,L,R);
		node b=ask(u*2+1,mid+1,r,L,R);
		node k=(node){max(max(a.lw,b.lw),a.maxw-b.minw),max(max(a.rw,b.rw),b.maxw-a.minw),max(a.maxw,b.maxw),min(a.minw,b.minw)};
		return k;
	}
	else
	{
		return (node){0,0,0,2000000000};
	}
}
int query(int x,int y,int k)
{
	int a=x,b=y;
	split(a,b);
	int ans=0;
	int maxn=0,minn=2e9;
	for(int p=0;p<=1;p++)
	{
		for(int i=0;i<rev[p].size();i++)
		{
			int u=rev[p][i]._begin,v=rev[p][i]._end;
			node k=ask(1,1,n,u,v);
			maxn=max(maxn,k.maxw);
			if(i==0)
			{
				ans=max(ans,max(maxn-minn,k.rw));
			}
			else
			{
				ans=max(ans,max(maxn-minn,k.rw));
			}
			minn=min(minn,k.minw);
		}
	}
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
		{
			swap(x,y);
		}
		update(1,1,n,dfn[top[x]],dfn[x],k);
		x=father[top[x]];
	}
	update(1,1,n,min(dfn[x],dfn[y]),max(dfn[x],dfn[y]),k);
	return ans;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n-1;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs1(1,0);
	dfs2(1,1);
	build(1,1,n);
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		int x,y,k;
		scanf("%d%d%d",&x,&y,&k);
		int ans=query(x,y,k);
		printf("%d\n",ans);
	}
	return 0;
}
2024/8/28 20:35
加载中...