BZOJ 题目3224: Tyvj 1728 普通平衡树(SBT有重)
2015-08-15 16:38
513 查看
3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 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
101 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
10646584185
492737
HINT
1.n的数据范围:n<=1000002.每个数的数据范围:[-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)); } } }
相关文章推荐
- oracle游标
- 【LeetCode】122.Best Time to Buy and Sell Stock II
- Android性能优化之布局优化
- bzoj-2002 Bounce 弹飞绵羊
- 小小菜之Cocos2d-x游戏开发旅程——项目实例:贪吃蛇(1)
- Opencv Mat的三种常用类型简介
- 自定义控件时init编写报错(注意事项)
- Opencv Mat的三种常用类型简介
- hdoj 5137 How Many Maos Does the Guanxi Worth 【枚举删点 + 最短路】
- hadoop 二次排序
- 字符统计
- 37 回文字符串
- OC中的类别解析
- 文件上传
- 积分不等式
- yii2 直接输出model的(active record)sql语句
- wpf 如何去掉字符串中的特殊字符,或者从字符串中去掉
- uva 11572 - Unique Snowflakes(和书略有不同)
- OC字典中添加相同key值需要注意的问题
- 百度站长平台lee:谈spider抓取过程中的策略