WA啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
查看原帖
WA啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
86624
洛谷Onlinejudge楼主2020/8/12 17:57
#include "bits/stdc++.h"
using namespace std;
#define MAXN 100010

struct EDGE{
	int Next,To;
}E[MAXN<<1];
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;
}

int Fa[MAXN],Tot[MAXN];
int Dep[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;
}

int A[MAXN],InPut[MAXN];
int ID[MAXN],Count,Top[MAXN];
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{
		int Right,Left;
		int LC,RC,Sum;
		bool Lazy;
	}Tree[MAXN<<2];
	inline int LeftSon(int i){return i<<1;}
	inline int RightSon(int i){return i<<1|1;}
	inline void PushUp(int i){
		if(Tree[i].Left==Tree[i].Right)
			return;
		int L=LeftSon(i),R=RightSon(i);
		Tree[i].Sum=Tree[L].Sum+Tree[R].Sum;
		if(Tree[L].RC==Tree[R].LC)
			Tree[i].Sum--;
		Tree[i].LC=Tree[L].LC;
		Tree[i].RC=Tree[R].RC;
		return;
	}
	inline void Tree_Build(int i,int Left,int Right){
		Tree[i].Left=Left;
		Tree[i].Right=Right;
		if(Left==Right){
			Tree[i].LC=Tree[i].RC=InPut[Left];
			Tree[i].Lazy=false;
			Tree[i].Sum=1;
			return;
		}
		int Mid=(Left+Right)>>1;
		int L=LeftSon(i),R=RightSon(i);
		Tree_Build(L,Left,Mid);
		Tree_Build(R,Mid+1,Right);
		PushUp(i);
		return;
	}
	inline void PushDown(int i){
		if(Tree[i].Lazy==false)
			return;
		if(Tree[i].Left==Tree[i].Right)
			return;
		int L=LeftSon(i),R=RightSon(i);
		Tree[R].LC=Tree[R].RC=Tree[i].RC;
		Tree[L].LC=Tree[L].RC=Tree[i].LC;
		Tree[L].Lazy=Tree[R].Lazy=true;
		Tree[L].Sum=Tree[R].Sum=1;
		Tree[i].Lazy=false;
		return;
	}
	inline void AddSeg(int i,int Left,int Right,int Add){
		if(Tree[i].Left>Right||Left>Tree[i].Right)
			return;
		if(Left<=Tree[i].Left&&Tree[i].Right<=Right){
			Tree[i].LC=Tree[i].RC=Add;
			Tree[i].Lazy=true;
			Tree[i].Sum=1;
			return;
		}
		PushDown(i);
		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);
		PushUp(i);
		return;
	}
	inline int SumSeg(int i,int Left,int Right){
		if(Tree[i].Left>Right||Left>Tree[i].Right)
			return 0;
		if(Left<=Tree[i].Left&&Tree[i].Right<=Right)
			return Tree[i].Sum;
		PushDown(i);
		int Sum=0,L=LeftSon(i),R=RightSon(i);
		if(Tree[L].Right>=Left)Sum+=SumSeg(L,Left,Right);
		if(Tree[R].Left<=Right)Sum+=SumSeg(R,Left,Right);
		return Sum;
	}
	inline int SearchColor(int i,int W){
		if(Tree[i].Left>W||W>Tree[i].Right)
			return 0;
		if(Tree[i].Left==Tree[i].Right)
			return Tree[i].LC;
		PushDown(i);
		int Sum=0,L=LeftSon(i),R=RightSon(i);
		if(Tree[L].Right>=W)Sum+=SearchColor(L,W);
		if(Tree[R].Left<=W)Sum+=SearchColor(R,W);
		return Sum;
	}
}Do;

inline void AddTree(int X,int Y,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 SumTree(int X,int Y){
	int Sum=0,XC=-1,YC=-1;
	while(Top[X]!=Top[Y]){
		if(Dep[Top[X]]<Dep[Top[Y]])
			swap(X,Y),swap(XC,YC);
		Sum+=Do.SumSeg(1,ID[Top[X]],ID[X]);
		if(Do.SearchColor(1,ID[X])==XC)
			Sum--;
		XC=Do.SearchColor(1,ID[Top[X]]);
		X=Fa[Top[X]];
	}
	if(Dep[X]>Dep[Y])
		swap(X,Y),swap(XC,YC);
	Sum+=Do.SumSeg(1,ID[X],ID[Y]);
	if(Do.SearchColor(1,ID[X])==XC)
		Sum--;
	if(Do.SearchColor(1,ID[Y])==YC)
		Sum--;
	return Sum;
}

inline int Read(void){
	int Y=1,X=0;char C=getchar();
	while(C<'0'||C>'9'){if(C=='-'){Y=-1;}C=getchar();}
	while('0'<=C&&C<='9'){X=X*10+(C-'0');C=getchar();}
	return (X*Y);
}

char Type;
int N,M,X,Y,Z;
int main(void){
	N=Read(),M=Read();
	for(register int i=1;i<=N;i++)
		A[i]=Read();
	for(register int i=1;i<N;i++){
		X=Read(),Y=Read();
		Add(X,Y),Add(Y,X);
	}
	DFS1(1,0),DFS2(1,1);
	Do.Tree_Build(1,1,N);
	for(register int i=1;i<=M;i++){
		Type=getchar();
		if(Type=='C'){
			X=Read(),Y=Read(),Z=Read();
			AddTree(X,Y,Z);
		}
		if(Type=='Q'){
			X=Read(),Y=Read();
			printf("%d\n",SumTree(X,Y));
		}
	} 
	return 0;
}

记录

救救孩子吧……

2020/8/12 17:57
加载中...