可持久化平衡树

/*
#include<iostream>
#include<random>

using namespace std;

const int INF=2147483647;
mt19937 Rand(time(nullptr));
struct node{
	node *l,*r;
	int val,siz,pri;
	
	node(int _val): l(nullptr),r(nullptr),val(_val),siz(1),pri(Rand()){}
	node(const node *u): l(u->l),r(u->r),val(u->val),siz(u->siz),pri(u->pri){}//克隆,即可持久化思想,将未改变的版本进行共用
	void pushup(){
		siz=1;
		if(l)
			siz+=l->siz;
		if(r)
			siz+=r->siz;
	}
};
struct FHQ_treap{
private:
	pair<node *,node *> split(node *u,int val){
		if(!u)
			return {nullptr,nullptr};
		auto newnode=new node(u);
		if(newnode->val<=val){
			auto tmp=split(newnode->r,val);
			newnode->r=tmp.first;
			newnode->pushup();
			return {newnode,tmp.second};
		}
		else{
			auto tmp=split(newnode->l,val);
			newnode->l=tmp.second;
			newnode->pushup();
			return {tmp.first,newnode};
		}
	}
	pair<node *,node *> splitori(node *u,int val){
		if(u==nullptr)
			return {nullptr,nullptr};
		if(u->val<=val){
			auto tmp=splitori(u->r,val);
			u->r=tmp.first;
			u->pushup();
			return {u,tmp.second};
		}
		else{
			auto tmp=splitori(u->l,val);
			u->l=tmp.second;
			u->pushup();
			return {tmp.first,u};
		}
	}
	node *merge(node *u,node *v){
		if(!u)
			return v? new node(v):nullptr;
		if(!v)
			return u? new node(u):nullptr;
		if(u->pri<v->pri){
			auto newnode=new node(u);
			newnode->r=merge(newnode->r,v->l);
			newnode->pushup();
			return newnode;
		}
		else{
			auto newnode=new node(v);
			newnode->l=merge(u,newnode->l);
			newnode->pushup();
			return newnode;
		}
	}
	node *mergeori(node *u,node *v){
		if(u==nullptr)
			return v;
		if(v==nullptr)
			return u;
		if(u->pri<v->pri){
			u->r=mergeori(u->r,v);
			u->pushup();
			return u;
		}
		else{
			v->l=mergeori(u,v->l);
			v->pushup();
			return v;
		}
	}
	node *insert(node *u,int val){
		auto tmp=split(u,val-1);
		auto newnode=new node(val);
		return merge(merge(tmp.first,newnode),tmp.second);
	}
	node *erase(node *u,int val){
		auto tmp=split(u,val-1);
		auto rtr=split(tmp.second,val);
		if(rtr.first){
			// 如果存在值为val的节点,删除它
			// 注意:这里不直接删除,因为可能有其他版本引用
			auto merged=merge(rtr.first->l,rtr.first->r);
			return merged;
		}
		return merge(tmp.first,merge(rtr.first,rtr.second));
	}
	int queryval(node *u,int val){
		auto tmp=splitori(u,val-1);
		int res=tmp.first==nullptr? 0+1:tmp.first->siz+1;
		return res;
	}
	int queryrank(node *u,int rnk){
		auto pos=u;
		while(pos){
			int lsiz=pos->l==nullptr? 0:pos->l->siz;
			if(rnk==lsiz+1)
				return pos->val;
			if(rnk<lsiz+1)
				pos=pos->l;
			else{
				rnk-=lsiz+1;
				pos=pos->r;
			}
		}
		return 0;
	}
public:
	vector<node *> versions;
	void init(){
		versions.push_back(nullptr);  
		// 版本0:空树
	}
	// 创建新版本
	int insert(int version,int val){
		node* newroot=insert(versions[version],val);
		versions.push_back(newroot);
		return versions.size()-1;
	}
	int erase(int version,int val){
		node* newroot=erase(versions[version],val);
		versions.push_back(newroot);
		return versions.size()-1;
	}
	int queryval(int version,int val){
		return queryval(versions[version],val);
	}
	int queryrank(int version, int k){
		return queryrank(versions[version], k);
	}
	int getpre(int version,int val){
		auto res=queryval(version,queryrank(version,val)-1);
		if(!res)
			return -INF;
		return res;
	}
	int getnext(int version,int val){
		auto res=queryval(version,queryrank(version,val+1));
		if(!res)
			return INF;
		return res;
	}
};
FHQ_treap tr;

int main(){
	cin.tie(nullptr)->sync_with_stdio(false);
	
}
*/
#include<bits/stdc++.h>
using namespace std;
//#define int long long
inline void read(int& a){
	int s=0, w=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if (ch=='-')
			w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		s=s*10+ch-'0';
		ch=getchar();
	}
	a=s*w;
}
void write(int x){
	if(x<0)
		putchar('-'),x=-x;
	if(x>9)
		write(x/10);
	putchar(x%10+'0');
	return;
}
const int N=3e7+5;
const int INF=2147483647;
int siz[N],ls[N],rs[N],val[N],pri[N],root[N];
int cnt,n;
void updata(int a,int b){
	siz[a]=siz[b];
	val[a]=val[b];
	pri[a]=pri[b];
	ls[a]=ls[b];
	rs[a]=rs[b];
}
void up(int x){
	if(x){
		siz[x]=siz[ls[x]]+siz[rs[x]]+1;
	}
}
void Split(int rt,int k,int &rt1,int &rt2){
	if(!rt){
		rt1=rt2=0;
		return;
	}
	int new_rt=++cnt;
	updata(new_rt,rt);
	if(k<val[rt]){
		rt2=new_rt;
		Split(ls[rt],k,rt1,ls[rt2]);
		up(rt2);
	}
	else{
		rt1=new_rt;
		Split(rs[rt],k,rs[rt1],rt2);
		up(rt1);
	}
}
int Merge(int rt1,int rt2){
	if(!rt1 || !rt2) return rt1|rt2;
	int new_rt=++cnt;
	if(pri[rt1]<pri[rt2]){
		updata(new_rt,rt1);
		rs[new_rt]=Merge(rs[new_rt],rt2);
		up(new_rt);
		return new_rt;
	}
	else{
		updata(new_rt,rt2);
		ls[new_rt]=Merge(rt1,ls[new_rt]);
		up(new_rt);
		return new_rt;
	}
}
int Rank(int rt,int v){
	if(!rt) return 0;
	if(v<val[rt]) return Rank(ls[rt],v);
	else return siz[ls[rt]]+Rank(rs[rt],v)+1;
}
void insert(int &root,int v){
	int new_rt=++cnt;
	val[cnt]=v;
	pri[cnt]=rand();
	siz[cnt]=1;
	ls[cnt]=rs[cnt]=0;
	if(!root){
		root=cnt;
		return;
	}
	int rt1,rt2;
	Split(root,v,rt1,rt2);
	root=Merge(Merge(rt1,new_rt),rt2);
}
void erase(int &root,int v){
	int rt1,rt2,rt3;
	Split(root,v,rt1,rt3);
	Split(rt1,v-1,rt1,rt2);
	if(rt2){
		int new_rt=Merge(ls[rt2],rs[rt2]);
		root=Merge(rt1,Merge(new_rt,rt3));
	}
	else root=Merge(rt1,rt3);
	
}
int Kth(int rt, int k) {
	if(k<=siz[ls[rt]]) return Kth(ls[rt],k);
	else if(k==siz[ls[rt]]+1) return val[rt];
	else return Kth(rs[rt],k-siz[ls[rt]]-1);
}
int pre(int rt,int x){
	if(!rt) return -INF;
	if(val[rt]<x) return max(val[rt],pre(rs[rt],x));
	else return pre(ls[rt],x);
}
int nex(int rt,int x){
	if(!rt) return INF;
	if(val[rt]>x) return min(val[rt],nex(ls[rt],x));
	else return nex(rs[rt],x);
}
signed main(){
	read(n);
	root[0]=0;
	for(int i=1;i<=n;i++){
		int v,opt,x;
		read(v),read(opt),read(x);
		root[i]=root[v];
		if(opt==1) insert(root[i],x);
		if(opt==2) erase(root[i],x);
		if(opt==3) write(Rank(root[i],x-1)+1),printf("\n");
		if(opt==4) write(Kth(root[i],x)),printf("\n");
		if(opt==5) write(pre(root[i],x)),printf("\n");
		if(opt==6) write(nex(root[i],x)),printf("\n");
	}
	return 0;
}

posted on 2026-01-08 16:38  _CENSORED  阅读(26)  评论(0)    收藏  举报

导航