【模版】Treap

#include<bits/stdc++.h>
#define mp make_pair
#define PII pair<string,int>
#define pb push_back
#define vec vector
#define All(x) x.begin(),x.end() 
#define INS(x) inserter(x,x.begin())
#define INF 0x3f3f3f3f
using namespace std;
const int mx=5e6+5;
const int mod=1e9+7;
//Task : Treap
//Author : cqbzly
inline int read() {
	int x=0,f=1; char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
	while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0'; c=getchar();}
	return x*f;
}
int n,m,res,last;
struct node{
	int key,fix,cnt,siz;
	node *ch[2];
};
//内存池 
node tree[mx];
node *Root,*NIL,*ncnt;
int rint(){
	return rand()%mod;
}
void PushUp(node *x) {
	if(x==NIL) return;
	x->siz=x->ch[0]->siz+x->ch[1]->siz+x->cnt;
}
//旋转同时修改当前根 
void Rotate(node *&x,int d) {
	node *y=x->ch[!d];
	x->ch[!d]=y->ch[d];
	y->ch[d]=x;
	x=y;
	PushUp(x->ch[d]);
	PushUp(x);
}
void Init() {
	NIL=&tree[0];
	NIL->ch[0]=NIL->ch[1]=NIL;
	NIL->fix=(1<<30)-1;
	ncnt=&tree[1];
	Root=NIL;
}
node *NewNode(int val) {
	node *p=ncnt++;
	p->key=val;
	p->ch[0]=p->ch[1]=NIL;
	p->cnt=p->siz=1;
	p->fix=rint()%mod;
	return p;
}
void Insert(node *&rt,int val) {
	if(rt==NIL) {
		rt=NewNode(val);
		return;
	}
	if(rt->key==val) {
		rt->cnt++; rt->siz++;
		return;
	}
	int d=(val>=rt->key);
	Insert(rt->ch[d],val);
	if(rt->ch[d]->fix<rt->fix) 
	    Rotate(rt,!d);
	PushUp(rt);
}
//相对排名 
int GetRank(node *rt,int val) {
	if(rt==NIL) return 1;
	if(val==rt->key) return rt->ch[0]->siz+1;
	if(val<rt->key) return GetRank(rt->ch[0],val);
	else return GetRank(rt->ch[1],val)+rt->ch[0]->siz+rt->cnt;
}
//选取中序第 k 大节点 
node *Select(node *rt,int k) {
	if(rt==NIL) return NIL;
	if(k<=rt->ch[0]->siz) return Select(rt->ch[0],k);
	else if(k<=rt->ch[0]->siz+rt->cnt) return rt;
	else return Select(rt->ch[1],k-(rt->ch[0]->siz+rt->cnt));
}
//查找前驱
node *FindPre(int val) {
	int k=GetRank(Root,val);
	node *p=Select(Root,k-1);
	return p;
} 
//查找后继 
node *FindNxt(int val) {
	int k=GetRank(Root,val+1);
	node *p=Select(Root,k);
	return p;
}
//迭代删除 (没有则不删除)
void Delete(node *&rt,int val) {
	//处理叶节点 
	if(rt->ch[0]==NIL&&rt->ch[1]==NIL) {
		if(rt->key==val) {
			rt->cnt--,rt->siz--;
			if(rt->cnt==0) rt=NIL;
		}
		return;
	}
	if(rt->key==val) {
		if(rt->cnt>1) {
			rt->cnt--,rt->siz--;
			return;
		}
		//下旋删除节点 
		else {
			int d=(rt->ch[0]->fix<rt->ch[1]->fix);
			Rotate(rt,d);
			Delete(rt->ch[d],val);
		}
	}
	else {
		int d=(val>=rt->key);
		Delete(rt->ch[d],val);
	}
	PushUp(rt);
}
int main() {
	srand(unsigned(time(0)));
	n=read(),m=read(); Init();
	for(int i=1;i<=n;i++) {
		int x=read();
		Insert(Root,x);
	}
	for(int i=1;i<=m;i++) {
		int op=read(),x=read();
		x^=last;
		if(op==1) {
			Insert(Root,x);
		}
		else if(op==2) {
			Delete(Root,x);
		}
		else if(op==3) {
			last=GetRank(Root,x);
			res^=last;
		}
		//不存在为空的情况 
		else if(op==4) {
			last=Select(Root,x)->key;
			res^=last;
		}
		else if(op==5) {
			last=FindPre(x)->key;
			res^=last;
		}
		else if(op==6) {
			last=FindNxt(x)->key;
			res^=last;
		}
	}
	printf("%d",res);
}
posted @ 2021-07-21 10:05  仰望星空的蚂蚁  阅读(12)  评论(0)    收藏  举报  来源