题目
思路:
没什么好说的,就是裸体的BST。
第一次做二叉树的题目,记录一下,以便以后查看。
需要注意的是找不到前驱的时候输出负无穷,找不到后继的时候输出正无穷…根据排名查找数字,找不到输出正无穷。
还有洛谷题解区的大佬有两位都写错了,测试样例给的没错,他们理解错了,(排名就是比这个数小的数的个数加1,那样例中的3不就排第二)。可能测试数据给的不够吧,他们居然都A了…
代码:
#include<bits/stdc++.h>
using namespace std;
const int inf=0x7fffffff;
//BST
int cont=0,ans;
struct node{
int ls,rs,val,siz,cnt;
}tree[500004];
//x 现在的节点 y 值
void insert(int x,int y){
tree[x].siz++;
if(tree[x].val==y){
tree[x].cnt++;
return;
}
if(tree[x].val>y){
if(tree[x].ls!=0)
insert(tree[x].ls,y);
else{
cont++;
tree[x].ls=cont;
tree[cont].cnt=tree[cont].siz=1;
tree[cont].val=y;
}
}
else{
if(tree[x].rs!=0)
insert(tree[x].rs,y);
else{
cont++;
tree[x].rs=cont;
tree[cont].cnt=tree[cont].siz=1;
tree[cont].val=y;
}
}
}
//x 现在的节点 val 值
int search(int x,int val){
if(x==0) return 0;
if(val==tree[x].val)return tree[tree[x].ls].siz;
if(val>tree[x].val)return tree[tree[x].ls].siz+tree[x].cnt+search(tree[x].rs,val);
if(val<tree[x].val)return search(tree[x].ls,val);
}
//y排名
int search2(int x,int y){
if(x==0) return inf;
if(tree[tree[x].ls].siz>=y)return search2(tree[x].ls,y);
if(tree[tree[x].ls].siz+tree[x].cnt>=y)return tree[x].val;
if(y>tree[tree[x].ls].siz)return search2(tree[x].rs,y-tree[tree[x].ls].siz-tree[x].cnt);
}
//找前驱
void searchf(int x,int val){
if(x==0) return;
if(tree[x].val<val){
ans=max(ans,tree[x].val);
searchf(tree[x].rs,val);
}
if(tree[x].val>=val){
searchf(tree[x].ls,val);
}
}
//找后继
void searchl(int x,int val){
if(x==0) return;
if(tree[x].val>val){
ans=min(ans,tree[x].val);
searchl(tree[x].ls,val);
}
if(tree[x].val<=val){
searchl(tree[x].rs,val);
}
}
int main(){
int n;
int type,num;
scanf("%d",&n);
while(n--){
scanf("%d %d",&type,&num);
if(type==5){
if(cont==0){
cont++;
tree[1].cnt=tree[1].siz=1;
tree[1].val=num;
}
else insert(1,num);
}
if(type==1)printf("%d\n",search(1,num)+1);//查找排名
if(type==2)printf("%d\n",search2(1,num));//依据排名查找数字
if(type==3)ans=-inf,searchf(1,num),printf("%d\n",ans);//查找前驱
if(type==4)ans=inf,searchl(1,num),printf("%d\n",ans);//查找后继
}
}