您的位置:首页 > 运维架构

维护集合Ⅰ【无旋Treap数组模板】

2017-10-07 11:39 288 查看
无旋treap模板题

题目描述

如未特别说明,以下所有数据均为整数。

维护一个多重集S ,初始为空,有以下几种操作:

1. 把 x 加入 S。

2. 删除 S 中的一个 x ,保证删除的 x 一定存在。

3. 求 S 中第 k 小。

4. 求 S 中有多少个元素小于x。

5. 求 S 中小于 x 的最大数。

6. 求 S 中大于 x 的最小数。

操作共 n 次 。

输入格式

第一行一个整数 n(1≤n≤3×10^5 ) ,表示共有 n 次操作 。

接下来 n 行,每行为以下几种格式之一 :

0 x,把 x(0 ≤x≤10^9 ) 加入 S 。

1 x,删除 S 中的一个 x,保证删除的数在 S 中一定存在 。

2 k,求 S 中第 k(1≤k≤|S|)小 。

3 x,求 S 中有多少个数小于 x(0≤x≤10^9) 。

4 x,求S 中小于 x(0≤x≤10^9 )的最大数,如果不存在,输出 -1。

5 x,求S 中大于 x(0≤x≤10^9 )的最小数,如果不存在,输出 -1。

输出格式

对于每次询问,输出单独一行表示答案。

样例数据 1

输入  [复制]

5

0 3

0 4

2 2

1 4

3 3

输出

4

0

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<ctime>
using namespace std;

int getint()
{
int i=0,f=1;char c;
for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());
if(c=='-')c=getchar(),f=-1;
for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';
return i*f;
}

const int N=300005;
int n,root,L,R;
int tot,val
,pri
,size
,son
[2];

int upt(int u)
{
size[u]=size[son[u][0]]+size[son[u][1]]+1;
return u;
}

int merge(int u,int v)
{
if(!u)return upt(v);
if(!v)return upt(u);
if(pri[u]<pri[v])
{
son[u][1]=merge(son[u][1],v);
return upt(u);
}
else
{
son[v][0]=merge(u,son[v][0]);
return upt(v);
}
}

void Split(int u,int v,int &L,int &R)
{
if(!u)
{
L=R=0;
return;
}
if(val[u]<=v)
{
Split(son[u][1],v,L,R);
son[u][1]=0,upt(u);
L=merge(u,L);
}
else
{
Split(son[u][0],v,L,R);
son[u][0]=0,upt(u);
R=merge(R,u);
}
}

void Split_Kth(int u,int kth,int &L,int &R)
{
if(!u)
{
L=R=0;
return;
}
if(size[son[u][0]]<kth)
{
Split_Kth(son[u][1],kth-size[son[u][0]]-1,L,R);
son[u][1]=0,upt(u);
L=merge(u,L);
}
else
{
Split_Kth(son[u][0],kth,L,R);
son[u][0]=0,upt(u);
R=merge(R,u);
}
}

void Insert(int v)
{
L=R=0;
Split(root,v,L,R);
val[++tot]=v,pri[tot]=rand();
root=merge(merge(L,tot),R);
}

void Delete(int v)
{
L=R=0;
int p=0,q=0;
Split(root,v,L,R);
Split_Kth(L,size[L]-1,p,q);
root=merge(p,R);
}

void Find_Kth(int k)
{
L=R=0;
Split_Kth(root,k,L,R);
int pos=L;
while(son[pos][1])pos=son[pos][1];
cout<<val[pos]<<'\n';
root=merge(L,R);
}

void Lower_count(int v)
{
L=R=0;
Split(root,v-1,L,R);
cout<<size[L]<<'\n';
root=merge(L,R);
}

void Upper_bound(int v)
{
L=R=0;
Split(root,v-1,L,R);
if(!L)
{
cout<<-1<<'\n';
return;
}
int pos=L;
while(son[pos][1])pos=son[pos][1];
cout<<val[pos]<<'\n';
root=merge(L,R);
}

void Lower_bound(int v)
{
L=R=0;
Split(root,v,L,R);
if(!R)
{
cout<<-1<<'\n';
return;
}
int pos=R;
while(son[pos][0])pos=son[pos][0];
cout<<val[pos]<<'\n';
root=merge(L,R);
}

int main()
{
//freopen("lx.in","r",stdin);
//freopen("lx.out","w",stdout);
int op,x;
srand(time(0));
n=getint();
while(n--)
{
op=getint(),x=getint();
if(op==0)Insert(x);
if(op==1)Delete(x);
if(op==2)Find_Kth(x);
if(op==3)Lower_count(x);
if(op==4)Upper_bound(x);
if(op==5)Lower_bound(x);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: