• FHQ Treap学习


    安利一下blog,看一下:https://www.luogu.org/blog/Chanis/fhq-treap

    code:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    #include<ctime>
    #include<cmath>
    const int maxn=500006;
    int n,m,q,x,y,z,cnt;
    int size[maxn],ch[maxn][3],val[maxn],rnd[maxn],root;
    inline int creat(int k)
    {
    	size[++cnt]=1;
    	val[cnt]=k;
    	rnd[cnt]=rand();
    	return cnt;
    }
    inline void update(int s)
    {
    	size[s]=size[ch[s][0]]+size[ch[s][1]]+1;
    }
    inline void split(int now,int &x,int &y,int k)
    {
    	if (!now) 
    	{
    		x=y=0;
    		return;
    	}
    	if (val[now]<=k)
    	{
    		x=now,split(ch[now][1],ch[now][1],y,k);
    	}
    	else 
    	{
    		y=now,split(ch[now][0],x,ch[now][0],k);
    	}
    	update(now);
    } 
    inline int merge(int a,int b)
    {
    	if (!a||!b) return a+b;
    	if (rnd[a]<rnd[b])
    	{
    		ch[a][1]=merge(ch[a][1],b);
    		update(a);
    		return a;
    	}
    	else 
    	{
    		ch[b][0]=merge(a,ch[b][0]);
    		update(b);
    		return b;
    	}
    }
    inline void insert(int k)
    {
    	int cur=creat(k);
    	split(root,x,y,k);
    	root=merge(merge(x,cur),y);
    }
    inline void del(int k)
    {
    		split(root,x,z,k);
    		split(x,x,y,k-1);
    		y=merge(ch[y][0],ch[y][1]);
    		root=merge(merge(x,y),z);//记得要先merge起x,y 
    }
    inline int find_k(int s,int k)
    {
    	for (;;)
    	{
    		if (size[ch[s][0]]>=k) s=ch[s][0]; //(注意是比较儿子的size,因为可能有一样的数)
    		else if (k==size[ch[s][0]]+1) return s;
    		else
    		{
    			k-=size[ch[s][0]]+1;
    			s=ch[s][1];	
    		} 
    	}
    }
    inline int pre(int s,int k)
    {
    	split(s,x,y,k-1);
    	int tmp=val[find_k(x,size[x])];
    	root=merge(x,y);
    	return tmp;
    }
    inline int nxt(int s,int k)
    {
    	split(s,x,y,k);
    	int tmp=val[find_k(y,1)];
    	root=merge(x,y);
    	return tmp;
    }
    inline void cout(int k) 
    {
    	printf("%d
    ",k);
    }
    int main()
    {
    	srand((unsigned)(time(NULL)));
    	std::cin>>m;
    	for (int i=1,q1,q2;i<=m;++i)
    	{
    		scanf("%d%d",&q1,&q2);
    		if (q1==1) 
    		{
    			int cur=creat(q2);
    			split(root,x,y,q2);
    			root=merge(merge(x,cur),y);
    		}
    		if (q1==2) 
    		{
    			split(root,x,z,q2);
                split(x,x,y,q2-1);
                y=merge(ch[y][0],ch[y][1]);
                root=merge(merge(x,y),z);
    //            del(q2);
    		}
    		if (q1==3) 
    		{
    			split(root,x,y,q2-1);
    			cout(size[x]+1);
    			root=merge(x,y);
    		}
    		if (q1==4) cout(val[find_k(root,q2)]);
    		if (q1==5) cout(pre(root,q2));
    		if (q1==6) cout(nxt(root,q2));
    	}
    	return 0;
    }
    
  • 相关阅读:
    DS博客作业03--栈和队列
    DS博客作业02--线性表
    DS博客作业01--日期抽象数据类型设计与实现
    C语言博客作业06--结构体&文件
    DS博客作业08--课程总结
    DS博客作业07--查找
    DS博客作业06--图
    DS博客作业05--树
    DS博客大作业--树 (陈梓灿组)
    DS博客作业03--栈和队列
  • 原文地址:https://www.cnblogs.com/bullshit/p/9587926.html
Copyright © 2020-2023  润新知