处理有父节点问题的平衡树

//洛谷P4847 银河英雄传说V2 
#include<bits/stdc++.h>
using namespace std;

using ll=long long;
const int N=2e5+5;
mt19937 Rand(time(0));
struct node{
	node *l,*r,*fa;
	ll val,sum;
	int siz,pri;
	node(ll v): l(nullptr),r(nullptr),fa(nullptr),val(v),sum(v),siz(1),pri(Rand()){}
};
node *pos[N];

ll getsum(node *u){
	return u? u->sum:0;
}
int getsiz(node *u){
	return u? u->siz:0;
}
int getrank(node *u){
	int res=getsiz(u->l)+1;
	while(u->fa){
		if(u==u->fa->r) res+=getsiz(u->fa->l)+1;
		u=u->fa;
	}
	return res;
}
void pushup(node *&u){
	u->siz=getsiz(u->l)+1+getsiz(u->r);
	u->sum=getsum(u->l)+u->val+getsum(u->r);
}
node *getroot(node *u){
	while(u->fa) u=u->fa;
	return u;
}
void split(node *u,int siz,node *&x,node *&y,node *fx,node *fy){
	if(!u){
		x=y=nullptr;
		return ;
	}
	int lsiz=getsiz(u->l);
	if(siz>=lsiz+1){
		x=u;
		split(u->r,siz-(lsiz+1),x->r,y,u,fy);
	}
	else{
		y=u;
		split(u->l,siz,x,y->l,fx,u);
	}
	if(x) x->fa=fx;
	if(y) y->fa=fy;
	pushup(u);
}
node *merge(node *x,node *y){
	if(!x || !y) return x? x:y;
	if(x->pri>y->pri){
		x->r=merge(x->r,y);
		x->r->fa=x;
		pushup(x);
		return x;
	}
	else{
		y->l=merge(x,y->l);
		y->l->fa=y;
		pushup(y);
		return y;
	}
}

int main(){
	cin.tie(nullptr)->sync_with_stdio(false);
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		int tmp;
		cin>>tmp;
		pos[i]=new node(tmp);
	}
	while(m--){
		char op;
		cin>>op;
		if(op=='M'){
			int x,y;
			cin>>x>>y;
			node *rtx=getroot(pos[x]),*rty=getroot(pos[y]);
			if(rtx!=rty) merge(rty,rtx);
		}
		else if(op=='D'){
			int x;
			cin>>x;
			int k=getrank(pos[x]);
			node *ltr,*rtr;
			split(getroot(pos[x]),k-1,ltr,rtr,nullptr,nullptr);
		}
		else{
			int x,y;
			cin>>x>>y;
			node *rtx=getroot(pos[x]),*rty=getroot(pos[y]);
			if(rtx!=rty){
				cout<<"-1\n";
				continue;
			}
			else{
				int kx=getrank(pos[x]);
				int ky=getrank(pos[y]);
				if(kx>ky){
					swap(kx,ky);   // 只交换排名,不交换 pos
				}
				node *ltr,*mtr,*rtr;
				split(rtx,ky,ltr,rtr,nullptr,nullptr);
				split(ltr,kx-1,ltr,mtr,nullptr,nullptr);
				cout<<getsum(mtr)<<"\n";
				merge(merge(ltr,mtr),rtr);
			}
		}
	}
	return 0;
}

posted on 2026-09-29 18:59  _CENSORED  阅读(10)  评论(0)    收藏  举报

导航