3224: Tyvj 1728 普通平衡树

终于想起来我今天干嘛了。

没错,我要写替罪羊树啊。

然后发现已经到晚上了 〒▽〒 简直不像话

数落一下发现今天学到的都好奇怪(。・・)ノ我的天我今天到底在干嘛。

于是还是水(抄)了一发替罪羊树。

写完之后感觉我整个人都要拍扁重建了。

不造为什么我的替罪羊树跑得木有SBT快,不科学啊。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
using namespace std;
template<class T>void read(T &x){
	static char c;
	static bool f;
	for(f=0;c=getchar(),!isdigit(c);)if(c=='-')f=1;
	for(x=0;isdigit(c);c=getchar())x=x*10+c-'0';
	if(f)x=-x;
}
const int N=200000+10;
const double alpha=0.75;
struct Node{
	Node *ch[2];
	int sz,v,cnt;
	bool ex;
	bool scapegoat(){
		return ch[0]->cnt>alpha*cnt+5||ch[1]->cnt>alpha*cnt+5;
	}
	void pushup(){
		sz=ch[0]->sz+ch[1]->sz+ex;
		cnt=ch[0]->cnt+ch[1]->cnt+1;
	}
};
struct ScapegoatTree{
	Node pool[N];
	Node *tail,*root,*null;
	Node *bc[N];
	Node *v[N];
	int bc_top,top;
	void init(){
		tail=pool;
		null=tail++;
		null->ch[0]=null->ch[1]=null;
		null->sz=null->v=null->cnt=0;
		root=null;
		bc_top=0;
	}
	Node *newnode(int v){
		Node *p;
		if(bc_top)p=bc[--bc_top];
		else p=++tail;
		p->ch[0]=p->ch[1]=null;
		p->v=v;
		p->sz=1;
		p->cnt=1;
		p->ex=true;
		return p;
	}
	void travel(Node *p){
		if(p==null)return;
		travel(p->ch[0]);
		if(p->ex)v[++top]=p;
		else bc[bc_top++]=p;
		travel(p->ch[1]);
	}
	Node *divide(int l,int r){
		if(l>r)return null;
		int mid=l+r>>1;
		Node *p=v[mid];
		p->ch[0]=divide(l,mid-1);
		p->ch[1]=divide(mid+1,r);
		p->pushup();
		return p;
	}
	void rebuild(Node *&p){
		top=0;
		travel(p);
		p=divide(1,top);
	}
	Node **insert(Node *&p,int val){
		if(p==null){
			p=newnode(val);
			return &null;
		}else{
			p->sz++;
			p->cnt++;
			int k=val>=p->v;
			Node **res=insert(p->ch[k],val);
			if(p->scapegoat())res=&p;
			return res;
		}
	}
	void insert(int val){
		Node **p=insert(root,val);
		if(*p!=null)rebuild(*p);
	}
	void erase(Node *p,int id){
		p->sz--;
		if(p->ex&&id==p->ch[0]->sz+1)
		p->ex=0;
		else{
			if(id<=p->ch[0]->sz+p->ex)
			erase(p->ch[0],id);
			else erase(p->ch[1],id-p->ch[0]->sz-p->ex);
		}
	}
	int rank(int val){
		Node *now=root;
		int ans=1;
		while(now!=null){
			if(now->v>=val)now=now->ch[0];
			else{
				ans+=now->ch[0]->sz+now->ex;
				now=now->ch[1];
			}
		}
		return ans;
	}
	int kth(int k){
		Node *now=root;
		while(now!=null){
			if(now->ex&&k==now->ch[0]->sz+1)
			return now->v;
			else if(k<=now->ch[0]->sz)
			now=now->ch[0];
			else{
				k-=now->ch[0]->sz+now->ex;
				now=now->ch[1];
			}
		}
	}
	void erase(int val){
		erase(root,rank(val));
		if(root->sz<alpha*root->cnt)rebuild(root);
	}
	int pre(int x){
		return kth(rank(x)-1);
	}
	int suc(int x){
		return kth(rank(x+1));
	}
}sc;
int main(){
	int n;read(n);
	int opt,x;
	sc.init();
	while(n--){
		read(opt);read(x);
		switch(opt){
			case 1:sc.insert(x);break;
			case 2:sc.erase(x);break;
			case 3:printf("%d\n",sc.rank(x));break;
			case 4:printf("%d\n",sc.kth(x));break;
			case 5:printf("%d\n",sc.pre(x));break;
			case 6:printf("%d\n",sc.suc(x));break;
		}
	}
	return 0;
}
		


你可能感兴趣的:(3224: Tyvj 1728 普通平衡树)