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
#include<bits/stdc++.h>
#define int long long int
#define INF 0x7f7f7f7f
using namespace std;
struct node
{
int ls, rs;
int key, pri;
int cnt, size;
} tree[100001];
int root, n, idx;
void pushup( int p )
{
tree[p].size = tree[tree[p].ls].size + tree[tree[p].rs].size + tree[p].cnt;
}
void rightrotate( int &p )
{
int q = tree[p].ls;
tree[p].ls = tree[q].rs;
tree[q].rs = p;
p = q;
pushup(tree[p].rs);
}
void leftrotate( int &p )
{
int q = tree[p].rs;
tree[p].rs = tree[q].ls;
tree[q].ls = p;
p = q;
pushup(tree[p].ls);
}
int getnode( int key )
{
tree[++idx].key = key;
tree[idx].pri = rand();
tree[idx].cnt = tree[idx].size = 1;
return idx;
}
void insert( int &p, int key )
{
if( p == 0 )
{
p = getnode(key);
return;
}
else if( tree[p].key > key )
{
insert( tree[p].ls, key );
if( tree[tree[p].ls].pri > tree[p].pri )
{
rightrotate( p );
}
}
else if( tree[p].key == key )
{
tree[p].cnt++;
}
else
{
insert( tree[p].rs, key );
if( tree[tree[p].rs].pri > tree[p].pri )
{
leftrotate( p );
}
}
pushup(p);
}
void remove( int &p, int key )
{
if( p == 0 )
{
return ;
}
if( tree[p].key > key )
{
remove( tree[p].ls, key );
}
else if( tree[p].key < key )
{
remove( tree[p].rs, key );
}
else if( tree[p].cnt > 1 )
{
tree[p].cnt--;
}
else
{
if( tree[p].rs == 0 && tree[p].ls != 0 )
{
rightrotate(p);
remove( tree[p].rs, key );
}
else if( tree[p].ls == 0 && tree[p].rs != 0 )
{
leftrotate(p);
remove( tree[p].ls, key );
}
else if( tree[tree[p].ls].pri > tree[tree[p].rs].pri )
{
rightrotate(p);
remove( tree[p].rs, key );
}
else if( tree[p].ls == 0 && tree[p].rs == 0 )
{
p = 0;
}
else
{
leftrotate(p);
remove( tree[p].ls, key );
}
}
pushup(p);
}
int getrank( int p, int key )
{
if( p == 0 )
{
return 1;
}
if( tree[p].key > key )
{
return getrank( tree[p].ls, key );
}
else if( tree[p].key < key )
{
return tree[tree[p].ls].size + tree[p].cnt + getrank( tree[p].rs, key );
}
else
{
return tree[tree[p].ls].size + 1;
}
}
int getkey( int p, int rank )
{
if( p == 0 )
{
return INF;
}
if( tree[tree[p].ls].size >= rank )
{
return getkey( tree[p].ls, rank );
}
else if( rank > tree[tree[p].ls].size + tree[p].cnt )
{
return getkey( tree[p].rs, rank - tree[tree[p].ls].size - tree[p].cnt );
}
else
{
return tree[p].key;
}
}
int getprev( int p, int key )
{
if( p == 0 )
{
return -INF;
}
if( tree[p].key >= key )
{
return getprev( tree[p].ls, key );
}
else
{
return max( tree[p].key, getprev( tree[p].rs, key ) );
}
}
int getnext( int p, int key )
{
if( p == 0 )
{
return INF;
}
if( tree[p].key <= key )
{
return getnext( tree[p].rs, key );
}
return min( tree[p].key, getnext( tree[p].ls, key ) );
}
signed main()
{
cin >> n;
for( int i = 1; i <= n; i++ )
{
int opt, x;
cin >> opt >> x;
if( opt == 1 )
{
insert( root, x );
}
else if( opt == 2 )
{
remove( root, x );
}
else if( opt == 3 )
{
cout << getrank( root, x ) << endl;
}
else if( opt == 4 )
{
cout << getkey( root, x ) << endl;
}
else if( opt == 5 )
{
cout << getprev( root, x ) << endl;
}
else if( opt == 6 )
{
cout << getnext( root, x ) << endl;
}
}
}