求助FHQ-Treap TLE 56分
查看原帖
求助FHQ-Treap TLE 56分
367521
roger_yrj楼主2023/5/10 18:25
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,INF=1145141919;
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*10+c-'0';c=getchar();}
	return x*f;
}

//-------------FHQ-Treap-------------

int n,root,ncnt,dl,dr,dx;

struct node{
	int l,r,rnd,v,root,siz;
}tr[N*2];

int get_node(int x){
	ncnt++;
	tr[ncnt].v=x;
	tr[ncnt].rnd=rand();
	tr[ncnt].siz=1;
	return ncnt;
}

void updata(int k){
	tr[k].siz=tr[tr[k].l].siz+tr[tr[k].r].siz+1;
}

void split(int k,int x,int &l,int &r){//k 为 FHQ-Treap 的根,l 和 r 为分裂出来左右两个树的根
	if(!k){//空树
		l=r=0;
		return;
	}
	if(tr[k].v<=x){//小了往右走
		l=k;
		split(tr[k].r,x,tr[k].r,r);
	}else{//大了往左走
		r=k;
		split(tr[k].l,x,l,tr[k].l);
	}
	updata(k); 
}

int merge(int l,int r){
	if(!l||!r)return l+r;//空树
	if(tr[l].v<=tr[r].v){//右树分进左儿子
		tr[l].r=merge(tr[l].r,r);
		updata(l);
		return l;
	}else{//左树分进右儿子
		tr[r].l=merge(l,tr[r].l);
		updata(r);
		return r;
	}
}

void insert(int x){
	split(root,x,dl,dr);
	root=merge(merge(dl,get_node(x)),dr);
}

void del(int x){
	split(root,x-1,dl,dr);
	split(dr,x,dx,dr);//分成 tl(<x),tx(x),tr(>x) 三棵树
	dx=merge(tr[dx].l,tr[dx].r);//把 tx 根节点删除
	root=merge(merge(dl,dx),dr);//重新合并到一起 
}

int query_rank(int x){
	split(root,x-1,dl,dr);
	int ret=tr[dl].siz+1;
	root=merge(dl,dr);
	return ret;
}

int query_num(int k,int x){//与Treap类似 
	if(k==0)return 0;
	if(x<=tr[tr[k].l].siz)return query_num(tr[k].l,x);
	else if(x>tr[tr[k].l].siz+1)return query_num(tr[k].r,x-tr[tr[k].l].siz-1);
	else return tr[k].v;
}

int query_pre(int x){
	split(root,x-1,dl,dr);
	int ret=query_num(dl,tr[dl].siz);
	root=merge(dl,dr);
	return ret;
}

int query_nxt(int x){
	split(root,x,dl,dr);
	int ret=query_num(dr,1);
	root=merge(dl,dr);
	return ret;
}

int main(){
	cin>>n;
	for(int i=1,op,x;i<=n;i++){
		op=read(),x=read();
		if(op==1)insert(x);
		else if(op==2)del(x);
		else if(op==3)printf("%d\n",query_rank(x));
		else if(op==4)printf("%d\n",query_num(root,x));
		else if(op==5)printf("%d\n",query_pre(x));
		else if(op==6)printf("%d\n",query_nxt(x));
	}
}
2023/5/10 18:25
加载中...