P3369 平衡树板子 Treap求调,58pts

QBW114514 2024-02-24 22:41:34
#include<bits/stdc++.h>
#define f(i,a,b) for(int i = a ; i<=b ; i++)
using namespace std;
const int N = 1e5+5;
int n,rt,op,x;
struct treap{
	int ls,rs;//左孩子,右孩子
	int key;//当前点的值
	int siz,pri;//子树大小,优先级 
}t[N]; 
int cnt;//总结点个数
void newnode(int x){//创建新节点。
    ++cnt;
    t[cnt].ls = t[cnt].rs = 0;
    t[cnt].key = x;
	t[cnt].siz = 1;
    t[cnt].pri = rand();
    return ;
}
#define l t[u].ls 
#define r t[u].rs 
void update(int u){
	t[u].siz = t[l].siz+t[r].siz+1;//合并siz数组 
	return ;
}
void rotate(int &u,int d){
	int k;
	if(!d){
		k = r;
		r = t[k].ls;
		t[k].ls = u;
	}else{
		k = l;
		l = t[k].rs;
		t[k].rs = u;
	}
	t[k].siz+=t[u].siz;//更新
	update(u);//合并siz 
	u = k;//更新u 
	return ; 
}
void insert(int &u,int x){//插入一个节点
    if(!u){//如果当前节点为空...
        newnode(x);//新建节点。
        u = cnt;//设置u。
        return;
    }
    t[u].siz++;//设置当前子树大小自增。
    if(t[u].key<=x){//如果当前节点的键值小于要插入的值...
        insert(r,x);//递归插入。
        if(t[u].pri<t[r].pri) rotate(u,0);//如果权值不满足要求,旋转。
    }
    else{//另一侧...
        insert(l,x);//递归。
        if(t[u].pri<t[l].pri) rotate(u,1);//旋转。
    }
    update(u);
	return; 
}
void del(int &u,int x){//删除元素...
    --t[u].siz;//siz自减。
    if(t[u].key==x){//如果删除的就是当前节点...
        if(!l&&!r){//如果当前节点是叶子...
            u = 0;//删除。
            return;
        }
        if(!l||!r){//如果只有一个子树...
            u = l+r;
            return;
        }
        if(t[l].pri<t[r].pri){//左儿子和右儿子权值...
            rotate(u,1);//旋转。
            del(r,x);//递归。
            return;
        }
        else{
            rotate(u,0);
            del(l,x);
            return;
        }
    }
    if(t[u].key<x) del(r,x);
    else del(l,x);
    update(u);
}
int rank1(int u,int x){
    if(!u) return 0;
    if(x>t[u].key) return t[l].siz+rank1(r,x)+1;
    return rank1(l,x);
}
int kth(int u,int k){
    if(t[l].siz == k-1) return t[u].key;
    else if(t[l].siz<k-1) return kth(r,k-t[l].siz-1);
    else return kth(l,k);
}
int pre(int u,int x){
    if(!u) return 0;
    if(t[u].key>=x) return pre(l,x);
    int tmp = pre(r,x);
    if(!tmp) return t[u].key;
    return tmp;
}
int post(int u,int x){
    if(!u) return 0;
    if(t[u].key<=x) return post(r,x);
    int tmp = post(l,x);
    if(!tmp) return t[u].key;
    return tmp;
}
int main(){
	srand(time(0));
	cin>>n;
	f(i,1,n){
		cin>>op>>x;
		if(op == 1) insert(rt,x);
		if(op == 2) del(rt,x);
		if(op == 3) cout<<rank1(rt,x)+1<<endl;
		if(op == 4) cout<<kth(rt,x)<<endl;
		if(op == 5) cout<<pre(rt,x)<<endl;
		if(op == 6) cout<<post(rt,x)<<endl;
	}
	return 0;
}

 

...全文
141 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

2,373

社区成员

发帖
与我相关
我的任务
社区描述
本社区专注于分享Linux驱动和Kernel源码分析解读
linuxharmonyosubuntu 个人社区 北京·大兴区
社区管理员
  • Coder个人博客
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧