您的位置:首页 > 其它

BZOJ 3224: Tyvj 1728 普通平衡树

2017-03-14 11:22 363 查看

 Tyvj 1728 普通平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 11382  Solved: 4859

[Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:

1. 插入x数

2. 删除x数(若有多个相同的数,因只删除一个)

3. 查询x数的排名(若有多个相同的数,因输出最小的排名)

4. 查询排名为x的数

5. 求x的前驱(前驱定义为小于x,且最大的数)

6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10

1 106465

4 1

1 317721

1 460929

1 644985

1 84185

1 89851

6 81968

1 492737

5 493598

Sample Output

106465

84185

492737

HINT

1.n的数据范围:n<=100000

2.每个数的数据范围:[-1e7,1e7]

数据如下http://pan.baidu.com/s/1jHMJwO2

Source

平衡树

我觉得自己的代码还是蛮赏心悦目的~

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<iomanip>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,size=0,ans,root;
struct data{int w,val,size,rd,ls,rs;}tr[100010];
inline void update(int x)
{tr[x].size=tr[tr[x].rs].size+tr[tr[x].ls].size+tr[x].w;}
inline void rturn(int &x)
{
int t=tr[x].ls;tr[x].ls=tr[t].rs;tr[t].rs=x;
tr[t].size=tr[x].size;update(x);x=t;
}
inline void lturn(int &x)
{
int t=tr[x].rs;tr[x].rs=tr[t].ls;tr[t].ls=x;
tr[t].size=tr[x].size;update(x);x=t;
}
inline void insert(int &x,int val)
{
if(x==0)
{++size;x=size;tr[x].w=tr[x].size=1;tr[x].val=val;tr[x].rd=rand();return;}
tr[x].size++;
if(tr[x].val==val)tr[x].w++;
else if(tr[x].val<val)
{
insert(tr[x].rs,val);
if(tr[x].rd>tr[tr[x].rs].rd)lturn(x);
}
else
{
insert(tr[x].ls,val);
if(tr[x].rd>tr[tr[x].ls].rd)rturn(x);
}
}
inline void dlt(int &x,int val)
{
if(x==0)return ;
if(tr[x].val==val)
{
if(tr[x].w>1){tr[x].w--;tr[x].size--;return;}
if(tr[x].ls*tr[x].rs==0)x=tr[x].ls+tr[x].rs;
else if(tr[tr[x].ls].rd<tr[tr[x].rs].rd)
{rturn(x);dlt(x,val);}
else lturn(x),dlt(x,val);
}
else if(val>tr[x].val) tr[x].size--,dlt(tr[x].rs,val);
else tr[x].size--,dlt(tr[x].ls,val);
}
inline int query_rank(int x,int val)
{
if(x==0)return 0;
if(tr[x].val==val)return tr[tr[x].ls].size+1;
if(tr[x].val>val)return query_rank(tr[x].ls,val);
else return tr[tr[x].ls].size+tr[x].w+query_rank(tr[x].rs,val);
}
inline int query_num(int x,int num)
{
if(x==0)return 0;
if(num<=tr[tr[x].ls].size)return query_num(tr[x].ls,num);
else if(num>tr[x].w+tr[tr[x].ls].size)
return query_num(tr[x].rs,num-tr[x].w-tr[tr[x].ls].size);
else return tr[x].val;
}
inline void query_pro(int x,int num)
{
if(x==0)return ;
if(tr[x].val<num)ans=x,query_pro(tr[x].rs,num);
else return query_pro(tr[x].ls,num);
}
inline void query_sub(int x,int num)
{
if(x==0)return ;
if(tr[x].val>num)ans=x,query_sub(tr[x].ls,num);
else return query_sub(tr[x].rs,num);
}
int main()
{
n=read();int opt,x;
for(int i=1;i<=n;i++)
{
opt=read();x=read();
switch(opt)
{
case 1:insert(root,x);break;
case 2:dlt(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",tr[ans].val);break;
case 6:ans=0;query_sub(root,x);printf("%d\n",tr[ans].val);break;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: