你说得对,但是FHQ可以O(n^2)草过去耶……
查看原帖
你说得对,但是FHQ可以O(n^2)草过去耶……
342185
__builtin_orz楼主2024/11/25 22:15

不是题解,违规紫衫。

查询 O(logn)O(\log n),合并 O(n)O(n),可过。

#include<cmath>
#include<cstdio>
#include<random>
std::mt19937 chaos(20071109);
struct FHQ{
	int siz,rnk,id,pos,tag;
	FHQ *lc,*rc;
	static FHQ *null;
	FHQ(){
		siz=rnk=id=pos=tag=0;
		lc=rc=this;
	}
	FHQ(int i,int p){
		siz=1,rnk=chaos();
		id=i,pos=p;
		tag=0;
		lc=rc=null;
	}
}*FHQ::null=new FHQ();
bool is_null(FHQ* now){
	return now==FHQ::null;
}
void update(FHQ* now){
	now->siz=now->lc->siz+now->rc->siz+1;
}
void make_tag(FHQ* now,int val){
	if(!is_null(now)){
		now->tag+=val;
		now->pos+=val;
	}
}
void spread(FHQ* now){
	make_tag(now->lc,now->tag);
	make_tag(now->rc,now->tag);
	now->tag=0;
}
void split(FHQ* now,FHQ*& L,FHQ*& R,int id){
	if(is_null(now))L=R=FHQ::null;
	else if(now->id<id){
		spread(L=now);
		split(L->rc,L->rc,R,id);
		update(L);
	}else{
		spread(R=now);
		split(R->lc,L,R->lc,id);
		update(R);
	}
}
FHQ* merge(FHQ* L,FHQ* R){
	if(is_null(L))return R;
	if(is_null(R))return L;
	if(L->rnk<R->rnk){
		spread(L);
		L->rc=merge(L->rc,R);
		update(L);
		return L;
	}else{
		spread(R);
		R->lc=merge(L,R->lc);
		update(R);
		return R;
	}
}
int index(FHQ* now,int id){
	if(id==now->id)return now->pos;
	spread(now);
	if(id<now->id)return index(now->lc,id);
	return index(now->rc,id);
}
void insert(FHQ*& now,int id,int pos){
	FHQ *L,*R;
	split(now,L,R,id);
	now=merge(L,merge(new FHQ(id,pos),R));
}
void Merge(FHQ*& L,FHQ*& R){
	if(!is_null(L)){
		spread(L);
		insert(R,L->id,L->pos);
		Merge(L->lc,R);
		Merge(L->rc,R);
		delete L;
		L=FHQ::null;
	}
}
#define _N_ 30005
int fa[_N_];
FHQ* tree[_N_];
int get_father(int x){
	return fa[x]==x?x:fa[x]=get_father(fa[x]);
}
int main(){
	for(int i=1;i<=30000;i++){
		fa[i]=i;
		tree[i]=new FHQ(i,1);
	}
	int m;
	scanf("%d",&m);
	while(m--){
		static char op[5];
		int x,y;
		scanf("%s%d%d",op,&x,&y);
		int fx=get_father(x);
		int fy=get_father(y);
		if(*op=='M'){
			make_tag(tree[fx],tree[fy]->siz);
			if(tree[fx]->siz<tree[fy]->siz){
				fa[fx]=fy;
				Merge(tree[fx],tree[fy]);
			}else{
				fa[fy]=fx;
				Merge(tree[fy],tree[fx]);
			}
		}else
		if(fx!=fy)printf("-1\n");
		else printf("%d\n",std::abs(index(tree[fx],x)-index(tree[fx],y))-1);
	}
	return 0;
}

(本来想骗分的,结果就过力)

不是题解,违规紫衫。

2024/11/25 22:15
加载中...