【模板】BZOJ 3685: 普通van Emde Boas树——Treap

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3685

据说神犇都是用zkw线段树水过的啊...

我蒟蒻只会写treap,加了fread之后8.5s卡过。
update:之前评测机抽风了,重新交了一遍,测了正常时间。(无耻地加了fwrite

某种意义上算是一道模板题吧。

(一开始我的删除操作写挂了,导致无限WA(捂脸

#include <bits/stdc++.h>
using namespace std;

const int MAXN=3e6+5, MAXB=3e7;
char BUF[MAXB], *cp=BUF;

void rd(int &x){
	x=0;
	while(*cp<'0'||'9'<*cp) cp++;
	while('0'<=*cp&&*cp<='9') x=x*10+*cp-'0', cp++;
}

int N, M, tot;

struct Node{
	Node *lc, *rc;
	int v, f;
}nd[MAXN], *root;

inline void rrot(Node *&x){Node *y=x->lc; x->lc=y->rc; y->rc=x; x=y;}
inline void lrot(Node *&x){Node *y=x->rc; x->rc=y->lc; y->lc=x; x=y;}

void ins(Node *&x, int v){
	if(!x){
		x=&nd[++tot]; x->v=v; x->f=rand();
		return;
	}
	if(v==x->v) return;
	else if(v<x->v){
		ins(x->lc, v);
		if(x->f>x->lc->f) rrot(x);
	}else{
		ins(x->rc, v);
		if(x->f>x->rc->f) lrot(x);
	}
}

void del(Node *&x, int v){
	if(!x) return;
	if(v==x->v){
		if(!x->lc){x=x->rc; return;}
		if(!x->rc){x=x->lc; return;}
		Node *y=x->rc, *z=y->lc;
		if(!z){y->lc=x->lc; x=y; return;}
		while(z->lc) y=z, z=z->lc;
		y->lc=z->rc; z->lc=x->lc; z->rc=x->rc; x=z; 
	}
	else if(v<x->v) del(x->lc, v);
	else del(x->rc, v);
}

int getmin(){
	if(!root) return -1;
	Node *x=root;
	while(x->lc) x=x->lc;
	return x->v;
}

int getmax(){
	if(!root) return -1;
	Node *x=root;
	while(x->rc) x=x->rc;
	return x->v;
}

int pre(int v){
	Node *x=root, *y=0;
	while(x){
		if(v<=x->v) x=x->lc;
		else y=x, x=x->rc;
	}
	if(!y) return -1;
	return y->v;
}

int suc(int v){
	Node *x=root, *y=0;
	while(x){
		if(v>=x->v) x=x->rc;
		else y=x, x=x->lc;
	}
	if(!y) return -1;
	return y->v;
}

int find(int v){
	for(Node *x=root; x;){
		if(v==x->v) return 1;
		else if(v<x->v) x=x->lc;
		else x=x->rc;
	}
	return -1;
}

int main(){
	srand(23333333);
	fread(BUF, 1, MAXB, stdin);
	rd(N),rd(M);
	for(int i=0, t, x; i<M; ++i){
		rd(t);
		if(t==1) rd(x),ins(root,x);
		else if(t==2) rd(x),del(root,x);
		else if(t==3) printf("%d\n", getmin());
		else if(t==4) printf("%d\n", getmax());
		else if(t==5) rd(x),printf("%d\n",pre(x));
		else if(t==6) rd(x),printf("%d\n",suc(x));
		else if(t==7) rd(x),printf("%d\n",find(x));
	}
	return 0;
}
posted @ 2017-04-05 21:33  will7101  阅读(219)  评论(0编辑  收藏  举报