Treap模板【玄学】

一个很好玩的Treap模板。

#include <cstdio>
#include <algorithm>
#include <cstdlib>

using namespace std;

const int maxx = 100000 + 100;
int n,m,num,flag,Ans,x,root;

struct Node{
    int lc,rc;
    int fix,v;
    int cnt,size;
}T[maxx];

inline int read(){
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0') {if(c == '-') f=-1; c=getchar();}
    while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*f;
}

void update(int i){
    T[i].size = T[T[i].lc].size + T[T[i].rc].size + T[i].cnt;
}

void lturn(int &i){
    int t = T[i].rc;
    T[i].rc = T[t].lc;
    T[t].lc = i;
    T[t].size = T[i].size;
    update(i);
    i = t;
}

void rturn(int &i){
    int t = T[i].lc;
    T[i].lc = T[t].rc;
    T[t].rc = i;
    T[t].size = T[i].size;
    update(i);
    i = t;
}

void insert(int &i,int x){
    if(i == 0){
		num++;
		i = num;
		T[i].size = T[i].cnt = 1;
		T[i].v = x;
		T[i].fix = rand();
		return;
    }
    T[i].size++;
    if(x == T[i].v) T[i].cnt++;
    if(x < T[i].v){
		insert(T[i].lc,x);
		if(T[T[i].lc].fix < T[i].fix) rturn(i);
	}
    if(x > T[i].v){
		insert(T[i].rc,x);
		if(T[T[i].rc].fix < T[i].fix) lturn(i);
	}
}

void remove(int &i,int x){
    if(i == 0) return;
    if(x > T[i].v)
		T[i].size--,remove(T[i].rc,x);
    if(x < T[i].v)
		T[i].size--,remove(T[i].lc,x);
    if(x == T[i].v){
		if(T[i].cnt > 1){
	    	T[i].size--;
	    	T[i].cnt--;
	    	return;
		}
		if(T[i].lc*T[i].rc == 0)
	    	i = T[i].lc + T[i].rc;
		else if(T[T[i].lc].fix < T[T[i].rc].fix)
	    	rturn(i),remove(i,x);
		else
	    	lturn(i),remove(i,x);
    }
}

int Query_rank(int i,int x){
    if(i == 0) return 0;
    if(T[i].v == x) return T[T[i].lc].size+1;
    if(T[i].v > x) return Query_rank(T[i].lc,x);
    if(T[i].v < x) return T[T[i].lc].size + T[i].cnt + Query_rank(T[i].rc,x);
}

int Query_num(int i,int x){
    if(i == 0) return 0;
    if(x <= T[T[i].lc].size)
		return Query_num(T[i].lc,x);
    if(x > T[T[i].lc].size + T[i].cnt)
		return Query_num(T[i].rc,x-T[T[i].lc].size-T[i].cnt);
    else return T[i].v;
}

void Query_pro(int i,int x){
    if(i == 0) return;
    if(T[i].v < x){
		Ans = i;
		Query_pro(T[i].rc,x);
    }
    else Query_pro(T[i].lc,x);
}

void Query_sub(int i,int x){
    if(i == 0) return;
    if(T[i].v > x){
		Ans = i;
		Query_sub(T[i].lc,x);
    }
    else Query_sub(T[i].rc,x);
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
		flag = read();
		x = read();
		switch(flag){
			case 1: insert(root,x);break;
			case 2: remove(root,x);break;
			case 3: printf("%d\n",Query_rank(root,x));break;
			case 4: printf("%d\n",Query_num(root,x)); break;
			case 5: Ans = 0;Query_pro(root,x);printf("%d\n",T[Ans].v);break;
			case 6: Ans = 0;Query_sub(root,x);printf("%d\n",T[Ans].v);break;
			default: printf(">.<");break;
		}
    }
    return 0;
}


upt 2017.3.26 :短了..好多

#include <cstdio>
#include <algorithm>
#include <cstring>

#define Rep( i , B , E ) for(int i=B;i<=E;i++)
#define For( i , B , E ) for(int i=B;i<=E;i++)

using namespace std;

const int maxx = 100000 + 25;

int n,m,root,num,flag,ans,x;
int ch[maxx][2],v[maxx],fix[maxx],size[maxx],cnt[maxx];

namespace Treap{

	void upt(int i) {size[i] = size[ch[i][0]] + size[ch[i][1]] + cnt[i];}

	int chk(int a,int b) {return a == b ? 20011025 : a > b;}

	void rotate(int &i,int f){
		int t = ch[i][f];
		ch[i][f] = ch[t][f^1];
		ch[t][f^1] = i;
		size[t] = size[i];
		upt(i);i = t;
	}

	void insert(int &i,int x){
		if(i == 0) {i = ++num;v[i] = x;fix[i] = rand();size[i] = cnt[i] = 1;return;}
		size[i] ++ ; if(v[i] == x) {cnt[i] ++;return;}
		int tmp = chk(x,v[i]); insert(ch[i][tmp] , x);
		if(fix[ch[i][tmp]] < fix[i]) rotate(i,tmp);
	}

	void remove(int &i,int x){
		if(i == 0) return;
		if(v[i] != x) size[i] -- , remove(ch[i][chk(x,v[i])] , x);
		if(v[i] == x){
			if(cnt[i] > 1) {cnt[i] --; size[i] --; return;}
			if(ch[i][0] * ch[i][1] == 0) i = ch[i][0] + ch[i][1];
			else rotate( i, chk(ch[i][0],ch[i][1]) ),remove(i,x);
		}
	}

	int Qrank(int i,int x){
		if(i == 0) return 0;if(v[i] == x) return size[ch[i][0]] + 1;
		return x < v[i] ? Qrank(ch[i][0],x) : size[ch[i][0]] + cnt[i] + Qrank(ch[i][1],x);
	}

	int order(int i,int x){
		if(i == 0) return 0;
		if(x > cnt[i] + size[ch[i][0]]) return order(ch[i][1] , x - cnt[i] - size[ch[i][0]]);
		else return x <= size[ch[i][0]] ? order(ch[i][0] , x) : v[i];
	}

	void Query(int i,int x,int f){
		if(i == 0) return;
		if(chk(v[i] , x) == f) {ans = i;return Query(ch[i][f^1],x,f);}
		else return Query(ch[i][f],x,f);
	}

}

using namespace Treap;

int main(){
	scanf("%d",&m);
    while( m-- ){
        scanf("%d%d",&flag,&x);
        switch(flag){
            case 1: insert(root,x);break;
            case 2: remove(root,x);break;
            case 3: printf("%d\n",Qrank(root,x));break;
            case 4: printf("%d\n",order(root,x));break;
            case 5: ans = 0;Query(root,x,0);printf("%d\n",v[ans]);break;
            case 6: ans = 0;Query(root,x,1);printf("%d\n",v[ans]);break;
            default: puts(">.< !");break;
        }
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值