★★ 输入文件:phs.in 输出文件:phs.out 简单对比
时间限制:1 s 内存限制:128 MB
【题目描述】
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
【输入格式】
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
【输出格式】
对于操作3,4,5,6每行输出一个数,表示对应答案
【样例输入】
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
【样例输出】
106465
84185
492737
【提示】
1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
* 题解:*
平衡树模板题,全是基础操作。新学者可当成模板学习。
Code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<ctime>
using namespace std;
struct node{
node *left,*right;
int v,p,cnt,sz;
}*root,*null=new node((node){null,null,0,0,0,0});
int in(){
int x=0; char ch=getchar(); bool f=true;
while (ch<'0' || ch>'9'){
if (ch=='-') f=false;
ch=getchar();
}
while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
if (!f) x=-x;
return x;
}
void push_up(node *x){
x->sz=x->left->sz+x->right->sz+x->cnt;
}
void lturn(node *&x){
node *y=x->right;
x->right=y->left; y->left=x;
y->sz=x->sz; push_up(x); x=y;
}
void rturn(node *&x){
node *y=x->left;
x->left=y->right; y->right=x;
y->sz=x->sz; push_up(x); x=y;
}
void Insert(node *&x,int k){
if (!x->sz){
x=new node;
x->left=x->right=null;
x->v=k; x->p=rand();
x->sz=x->cnt=1;
return;
}
x->sz++;
if (k==x->v) x->cnt++;
else if (k>x->v){
Insert(x->right,k);
if (x->right->p<x->p) lturn(x);
}
else {
Insert(x->left,k);
if (x->left->p<x->p) rturn(x);
}
}
void Delete(node *&x,int k){
if (!x->sz) return;
if (k==x->v){
if (x->cnt>1) x->cnt--,x->sz--;
else if (!x->left->sz || !x->right->sz){
node *t=x;
if (!x->left->sz) x=x->right;
else x=x->left;
delete t;
}
else if (x->left->p<x->right->p)
rturn(x),Delete(x,k);
else lturn(x),Delete(x,k);
}
else if (k<x->v) x->sz--,Delete(x->left,k);
else x->sz--,Delete(x->right,k);
}
int Q_rank(node *x,int k){
if (!x->sz) return 0;
if (k==x->v) return x->left->sz+1;
else if (k<x->v) return Q_rank(x->left,k);
else return Q_rank(x->right,k)+x->left->sz+x->cnt;
}
int Q_num(node *x,int k){
if (!x->sz) return 0;
if (k<=x->left->sz) return Q_num(x->left,k);
else if (k>x->left->sz+x->cnt)
return Q_num(x->right,k-x->left->sz-x->cnt);
else return x->v;
}
int Q_pro(node *x,int k,int c){
if (!x->sz) return c;
if (k>x->v) return Q_pro(x->right,k,x->v);
else return Q_pro(x->left,k,c);
}
int Q_suc(node *x,int k,int c){
if (!x->sz) return c;
if (k<x->v) return Q_suc(x->left,k,x->v);
else return Q_suc(x->right,k,c);
}
int main(){
int n=in(); root=null; srand(time(0));
while (n--){
int opt=in(),x=in();
switch (opt){
case 1:Insert(root,x); break;
case 2:Delete(root,x); break;
case 3:printf("%d\n",Q_rank(root,x)); break;
case 4:printf("%d\n",Q_num(root,x)); break;
case 5:printf("%d\n",Q_pro(root,x,0)); break;
case 6:printf("%d\n",Q_suc(root,x,0)); break;
}
}
return 0;
}