pre()函数和getpre()虽类似,但是还有稍许不同,具体用时具体考虑。
#include<bits/stdc++.h>
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int maxn = 1e5+5;
int T[maxn<<2];
void build(int rt, int l, int r){
if(l == r) {T[rt] = 0; return ;}
int mid = l+r >> 1;
build(ls, l, mid); build(rs, mid+1, r);
T[rt] = T[ls] + T[rs];
}
void update(int rt, int l, int r, int pos){
if(l == r) {T[rt] = 1; return ;}
int mid = l+r >> 1;
if(pos <= mid) update(ls, l, mid, pos);
else update(rs, mid+1, r, pos);
T[rt] = T[ls] + T[rs];
}
int Rank(int rt, int l, int r, int x){ //rank of x (x is existed)
if(l == r) return 1;
int mid = l+r >> 1;
if(x <= mid) return Rank(ls, l, mid, x);
else return T[ls] + Rank(rs, mid+1, r, x);
}
int query(int rt, int l, int r, int k){ //the number whose rank is k
if(l == r) return l;
int mid = l+r >> 1;
if(k <= T[ls]) return query(ls, l, mid, k);
else return query(rs, mid+1, r, k-T[ls]);
}
int pre(int rt, int n, int x){ //前驱
int k = Rank(1, 1, n, x);
if(k == 1) return -1; //无前驱
return query(1, 1, n, k-1);
}
int nxt(int rt, int n, int x){ //后继
int k = Rank(1, 1, n, x);
if(k == T[1]) return -1; //无后继
return query(1, 1, n, k+1);
}
//与x的前驱类似,但不相同
int getpre(int rt, int l, int r, int x){ //<=x,且与x的差值最小的数
if(!T[rt]) return 0;
if(l == r) return l;
int mid = l+r >> 1;
if(x <= mid) return getpre(ls, l, mid, x);
int t = getpre(rs, mid+1, r, x);
if(t) return t;
return getpre(ls, l, mid, x);
}
int getnxt(int rt, int l, int r, int x){ //>=x,且与x的差值最小的数
if(!T[rt]) return 0;
if(l == r) return l;
int mid = l+r >> 1;
if(x > mid) return getnxt(rs, mid+1, r, x);
int t = getnxt(ls, l, mid, x);
if(t) return t;
return getnxt(rs, mid+1, r, x);
}
int n, a[maxn];
int main()
{
int l, r, x, op; n = 10;
while(cin >> op >> x){
if(op == 1) update(1, 1, n, x);
else if(op == 2) cout << Rank(1, 1, n, x) << endl;
else if(op == 3) cout << query(1, 1, n, x) << endl;
else if(op == 4) cout << pre(1, n, x) << endl;
else if(op == 5) cout << nxt(1, n, x) << endl;
else if(op == 6) cout << getpre(1, 1, n, x) << endl;
else cout << getnxt(1, 1, n, x) << endl;
}
}