80分求助
查看原帖
80分求助
86624
洛谷Onlinejudge楼主2020/8/9 00:01
#include "bits/stdc++.h"
using namespace std;
#define MAXN 101000

struct EDGE{
	int Next,To;
}E[MAXN<<1];
unsigned int Head[MAXN<<1],Size;
inline void Add(int From,int To){
	E[++Size].Next=Head[From];
	Head[From]=Size;
	E[Size].To=To;
	return;
}

unsigned int Dep[MAXN],Fa[MAXN];
unsigned int Tot[MAXN],Son[MAXN];
inline void DFS1(int This,int F){
	Fa[This]=F;
	Tot[This]=1;
	int MaxSon=0;
	Dep[This]=Dep[F]+1;
	for(register int i=Head[This];i;i=E[i].Next){
		int To=E[i].To;
		if(To==F)continue;
		DFS1(To,This);
		Tot[This]+=Tot[To];
		if(MaxSon<Tot[To]){
			MaxSon=Tot[To];
			Son[This]=To;
		}
	}
	return;
}

unsigned int A[MAXN],InPut[MAXN];
unsigned int Top[MAXN],ID[MAXN],Count;
inline void DFS2(int This,int Topf){
	Top[This]=Topf;
	ID[This]=(++Count);
	InPut[Count]=A[This];
	if(Son[This]==0)
		return;
	DFS2(Son[This],Topf);
	for(register int i=Head[This];i;i=E[i].Next){
		int To=E[i].To;
		if(To==Fa[This]||To==Son[This])
			continue;
		DFS2(To,To);
	}
	return;
}

struct NPC{
	struct SegmentTree{
		unsigned int Left,Right;
		unsigned int Lazy,Num;
	}Tree[MAXN<<2];
	inline int LeftSon(int i){return i<<1;}
	inline int RightSon(int i){return i<<1|1;}
	inline void Tree_Build(int i,int Left,int Right){
		Tree[i].Left=Left;
		Tree[i].Right=Right;
		if(Left==Right){
			Tree[i].Num=InPut[Left];
			return;
		}
		unsigned int Mid=(Left+Right)>>1;
		unsigned int L=LeftSon(i),R=RightSon(i);
		Tree_Build(L,Left,Mid);
		Tree_Build(R,Mid+1,Right);
		Tree[i].Num=min(Tree[L].Num,Tree[R].Num);
		return;
	}
	inline void PushDown(int i){
		if(Tree[i].Lazy==0)
			return;
		unsigned int L=LeftSon(i),R=RightSon(i);
		Tree[L].Lazy=Tree[R].Lazy=Tree[i].Lazy;
		Tree[L].Num=Tree[R].Num=Tree[i].Lazy;
		Tree[i].Lazy=0;
		return;
	}
	inline void AddSeg(int i,int Left,int Right,int Add){
		if(Tree[i].Right<Left||Right<Tree[i].Left)
			return;
		if(Left<=Tree[i].Left&&Tree[i].Right<=Right){
			Tree[i].Lazy=Add;
			Tree[i].Num=Add;
			return;
		}
		PushDown(i);
		unsigned int L=LeftSon(i),R=RightSon(i);
		if(Tree[L].Right>=Left)AddSeg(L,Left,Right,Add);
		if(Tree[R].Left<=Right)AddSeg(R,Left,Right,Add);
		Tree[i].Num=min(Tree[L].Num,Tree[R].Num);
		return;
	}
	#define INF 2147483648
	inline unsigned int MinSeg(int i,int Left,int Right){
		if(Tree[i].Right<Left||Right<Tree[i].Left)
			return INF;
		if(Left<=Tree[i].Left&&Tree[i].Right<=Right)
			return Tree[i].Num;
		PushDown(i);
		unsigned int Min=INF,L=LeftSon(i),R=RightSon(i);
		if(Tree[L].Right>=Left)Min=min(Min,MinSeg(L,Left,Right));
		if(Tree[R].Left<=Right)Min=min(Min,MinSeg(R,Left,Right));
		return Min;
	}
}Do;

inline void Cover(int X,int Y,unsigned int Z){
	while(Top[X]!=Top[Y]){
		if(Dep[Top[X]]<Dep[Top[Y]])
			swap(X,Y);
		Do.AddSeg(1,ID[Top[X]],ID[X],Z);
		X=Fa[Top[X]];
	}
	if(Dep[X]>Dep[Y])
		swap(X,Y);
	Do.AddSeg(1,ID[X],ID[Y],Z);
	return;
}

inline int Find(int F,int This){
	while(Top[This]!=Top[F]){
		if(Fa[Top[This]]==F)
			return Top[This];
		This=Fa[Top[This]];
	}
	return Son[F];
}

unsigned int Root,Tmp,SR;
unsigned int N,M,X,Y,Z,D;
int main(void){
	scanf("%d%d",&N,&M);
	for(register int i=1;i<N;i++){
		scanf("%d%d",&X,&Y);
		Add(X,Y),Add(Y,X);
	}
	for(register int i=1;i<=N;i++)
		scanf("%d",&A[i]);
	scanf("%d",&Root);
	DFS1(Root,0);
	DFS2(Root,Root);
	Do.Tree_Build(1,1,N);
	for(register int i=1;i<=M;i++){
		scanf("%d",&D);
		if(D==1)scanf("%d",&Root);
		else if(D==2){
			scanf("%d%d%d",&X,&Y,&Z);
			Cover(X,Y,Z);
		}
		else if(D==3){
			scanf("%d",&X);
			if(ID[Root]==ID[X])
				printf("%d\n",Do.MinSeg(1,1,N));
			#define SumSon (ID[X]+Tot[X]-1)
			else if(ID[Root]<ID[X]||ID[Root]>SumSon)
				printf("%d\n",Do.MinSeg(1,ID[X],SumSon));
			else if(ID[X]<ID[Root]&&ID[Root]<=SumSon){
				Tmp=INF,SR=Find(X,Root);
				Tmp=min(Tmp,Do.MinSeg(1,ID[SR]+Tot[SR],N));
				Tmp=min(Tmp,Do.MinSeg(1,1,ID[X]));
				printf("%d\n",Tmp);
			}
		}
	}
	return 0;
}

第六第十个点WA

2020/8/9 00:01
加载中...