3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 4350 Solved: 1769
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)); } } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-12 20:09:58