• treap学习


    treap相对splay容易理解

    对每个节点x,tr[x].rd=rand();

    然后对tr[x].rd操作,使其满足堆性质

    #include<bits/stdc++.h>
    #define maxn 1000005
    #define ls tr[k].l
    #define rs tr[k].r
    using namespace std;
    int n,rt,size;
    struct tree{
    	int l,r,sz,cnt,rd,v;
    }tr[maxn];
    inline int ran(){
        static int seed = 2333;
        return seed = (int)((((seed ^ 998244353) + 19260817ll) * 19890604ll) % 1000000007);
    }
    void update(int k)
    {
    	tr[k].sz=tr[ls].sz+tr[rs].sz+tr[k].cnt;
    }
    void lturn(int &k)
    {
    	int t=rs;rs=tr[t].l;tr[t].l=k;
    	tr[t].sz=tr[k].sz;update(k);k=t;
    }
    void rturn(int &k)
    {
    	int t=ls;ls=tr[t].r;tr[t].r=k;
    	tr[t].sz=tr[k].sz;update(k);k=t;
    }
    void insert(int &k,int x)
    {
    	if(k==0)
    	{
    		++size;k=size;
    		tr[k].cnt=tr[k].sz=1;
    		tr[k].v=x;
    		tr[k].rd=ran();
    		return;
    	}
    	tr[k].sz++;
    	if(x==tr[k].v)tr[k].cnt++;
    	else if(x<tr[k].v)
    	{
    		insert(ls,x);
    		if(tr[ls].rd<tr[k].rd)rturn(k);
    	}
    	else 
    	{
    		insert(rs,x);
    		if(tr[rs].rd<tr[k].rd)lturn(k);
    	}
    }
    void del(int &k,int x)
    {
    	if(k==0)return;
    	if(tr[k].v==x)
    	{
    		if(tr[k].cnt>=2){tr[k].cnt--;tr[k].sz--;return;}
    		if(ls==0||rs==0)k=ls+rs;
    		else {
    			if(tr[ls].rd<tr[rs].rd)rturn(k),del(k,x);
    			else lturn(k),del(k,x);
    		}
    	}
    	else if(tr[k].v<x)tr[k].sz--,del(rs,x);
    	else tr[k].sz--,del(ls,x);
    }
    int find_pm(int k,int x)
    {
    	if(k==0)return 0;
    	if(tr[k].v==x)return tr[ls].sz+1;
    	if(tr[k].v>x)return find_pm(ls,x);
    	else return tr[ls].sz+tr[k].cnt+find_pm(rs,x);
    }
    int find_wz(int k,int x)
    {
    	if(k==0)return 0;
    	if(x<=tr[ls].sz)return find_wz(ls,x);
    	else if(x>tr[ls].sz+tr[k].cnt)return find_wz(rs,x-tr[k].cnt-tr[ls].sz);
    	else return tr[k].v;
    }
    int find_qq(int k,int x)
    {
    	if(k==0)return -1e9;
    	if(tr[k].v<x)return max(tr[k].v,find_qq(rs,x));
    	return find_qq(ls,x);
    }
    int find_hj(int k,int x)
    {
    	if(k==0)return 1e9;
    	if(tr[k].v>x)return min(tr[k].v,find_hj(ls,x));
    	return find_hj(rs,x);
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		int temp,x;
     		scanf("%d%d",&temp,&x);
    		if(temp==1)insert(rt,x);
    		if(temp==2)del(rt,x);
    		if(temp==3)printf("%d
    ",find_pm(rt,x));
    		if(temp==4)printf("%d
    ",find_wz(rt,x));
    		if(temp==5)printf("%d
    ",find_qq(rt,x));
    		if(temp==6)printf("%d
    ",find_hj(rt,x));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    c++新特性之std::atomic
    PyQt 演示Demo1
    RxCPP(二)关键元素
    c++11 random_device 真随机数最简单应用
    PyQT5 安装与入门
    RxCPP(一)编程模型入门 调度
    RxCpp(四)Qt/GUI编程
    RxCPP(一)编程模型入门
    Flask 学习80.FlaskRESTX使用reqparse 解析器trim=True去掉字符两边空格 上海
    Flask 学习81.FlaskRESTX使用reqparse 解析器去掉值为None的参数 上海
  • 原文地址:https://www.cnblogs.com/hlsb/p/8532408.html
Copyright © 2020-2023  润新知