您的位置:首页 > 其它

BZOJ 题目3224: Tyvj 1728 普通平衡树(SBT有重)

2015-08-15 16:38 513 查看

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec Memory Limit: 128 MB

Submit: 4350 Solved: 1769

[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]

Source

平衡树
好吧,,从昨天就一直改这个代码,,,右旋的时候size少加了1,,,re一片啊,主要这个是有重的。
ac代码

/**************************************************************
Problem: 3224
User: kxh1995
Language: C++
Result: Accepted
Time:484 ms
Memory:47708 kb
****************************************************************/

#include<stdio.h>
#include<string.h>
#define min(a,b) (a>b?b:a)
#define INF 0xfffffff
struct s
{
int key,left,right,size,sc,cnt;
}tree[2001000];
int top,root;
void left_rot(int &x)
{
int y=tree[x].right;
tree[x].right=tree[y].left;
tree[y].left=x;
tree[y].size=tree[x].size;
tree[y].sc=tree[x].sc;
tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
tree[x].sc=tree[tree[x].left].sc+tree[tree[x].right].sc+tree[x].cnt;
x=y;
}
void right_rot(int &x)
{
int y=tree[x].left;
tree[x].left=tree[y].right;
tree[y].right=x;
tree[y].size=tree[x].size;
tree[y].sc=tree[x].sc;
tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
tree[x].sc=tree[tree[x].left].sc+tree[tree[x].right].sc+tree[x].cnt;
x=y;
}
void maintain(int &x,bool flag)
{
tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
tree[x].sc=tree[tree[x].left].sc+tree[tree[x].right].sc+tree[x].cnt;
if(flag==false)
{
if(tree[tree[tree[x].left].left].size>tree[tree[x].right].size)
right_rot(x);
else
if(tree[tree[tree[x].left].right].size>tree[tree[x].right].size)
{
left_rot(tree[x].left);
right_rot(x);
}
else
return;
}
else
{
if(tree[tree[tree[x].right].right].size>tree[tree[x].left].size)
left_rot(x);
else
if(tree[tree[tree[x].right].left].size>tree[tree[x].left].size)
{
right_rot(tree[x].right);
left_rot(x);
}
else
return;
}
maintain(tree[x].left,false);
maintain(tree[x].right,true);
maintain(x,true);
maintain(x,false);
}
void insert(int &x,int key)
{
if(x==0)
{
x=++top;
//  tree[x].left=0;
//  tree[x].right=0;
tree[x].size=tree[x].sc=tree[x].cnt=1;
tree[x].key=key;
}
else
{
// tree[x].size++;
if(tree[x].key==key)
{
tree[x].cnt++;
tree[x].sc++;
}
else
if(key<tree[x].key)
{
insert(tree[x].left,key);
maintain(x,false);
}
else
{
insert(tree[x].right,key);
maintain(x,true);
}
maintain(x,key>=tree[x].key);
}
}
void remove(int &x,int key)
{
if(tree[x].key==key)
{
if(tree[x].cnt>1)
{
tree[x].cnt--;
tree[x].sc--;
}
else
if(!tree[x].left&&!tree[x].right)
{
x=0;
}
else
if(!(tree[x].left*tree[x].right))
x=tree[x].left+tree[x].right;
else
if(tree[tree[x].left].size>tree[tree[x].right].size)
{
right_rot(x);
remove(tree[x].right,key);
maintain(x,false);
}
else
{
left_rot(x);
remove(tree[x].left,key);
maintain(x,true);
}
}
else
if(key<tree[x].key)
{
remove(tree[x].left,key);
maintain(x,true);
}
else
{
remove(tree[x].right,key);
maintain(x,false);
}
}
int getmin(int x)
{
while(tree[x].left)
x=tree[x].left;
return tree[x].key;
}
int getmax(int x)
{
while(tree[x].right)
x=tree[x].right;
return tree[x].key;
}
int pred(int &x,int y,int key)
{
if(x==0)
{
return tree[y].key;
}
if(key>tree[x].key)
return pred(tree[x].right,x,key);
else
return pred(tree[x].left,y,key);
}
int succ(int &x,int y,int key)
{
if(x==0)
{
return tree[y].key;
}
if(key<tree[x].key)
return succ(tree[x].left,x,key);
else
return succ(tree[x].right,y,key);
}
int get_min_k(int &x,int k)//选第k小的数
{
if(tree[tree[x].left].sc<k&&k<=tree[tree[x].left].sc+tree[x].cnt)
return tree[x].key;
if(k<=tree[tree[x].left].sc)
return get_min_k(tree[x].left,k);
else
return get_min_k(tree[x].right,k-tree[tree[x].left].sc-tree[x].cnt);
}
int rank(int &x,int key)//key排第几
{
if(key<tree[x].key)
{
return rank(tree[x].left,key);
}
else
if(key>tree[x].key)
return rank(tree[x].right,key)+tree[tree[x].left].sc+tree[x].cnt;
else
return tree[tree[x].left].sc+1;
}
int main()
{
int n,m;
while(scanf("%d",&n)!=EOF)
{
int i;
top=root=0;
while(n--)
{
int op,x;
scanf("%d%d",&op,&x);
if(op==1)
insert(root,x);
else
if(op==2)
{
remove(root,x);
}
else
if(op==3)
{
printf("%d\n",rank(root,x));
}
else
if(op==4)
{
printf("%d\n",get_min_k(root,x));
}
else
if(op==5)
{
printf("%d\n",pred(root,0,x));
}
else
printf("%d\n",succ(root,0,x));
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: