用二叉搜索树写的,想试试指针。样例能过没问题,自己做数据测了测也没毛病,交上去全部RE,不知道为什么。
#include <bits/stdc++.h>
using namespace std;
struct node {
int val, rec, siz;
node *fa, *son[2];
};
class Tree {
public:
node *rt = NULL;
void insert(int);
int find(int);
int kth(int);
int pre(int);
int nxt(int);
} tr;
void Tree::insert(int x) {
if (rt == NULL) {
rt = new node;
rt->val = x;
rt->siz = rt->rec = 1;
rt->fa = rt->son[0] = rt->son[1] = NULL;
//cout << "new root" << endl;
return;
}
node *now = rt, *f = NULL;
while (1) {
if (now->val == x) {
now->rec++;
now->siz++;
return;
}
f = now;
now = f->son[f->val < x];
f->siz++;
if (now == NULL) {
now = new node;
now->fa = f;
now->val = x;
now->son[0] = now->son[1] = NULL;
f->son[f->val < x] = now;
now->siz = now->rec = 1;
return;
}
}
}
int Tree::find(int x) {
node *now = rt;
int ans = 0;
while (1) {
if (now->son[0] != NULL && now->val > x) {
now = now->son[0];
continue;
}
if (now->son[0] != NULL) {
ans += now->son[0]->siz;
}
if (now->val == x) {
return ans + 1;
}
ans += now->rec;
now = now->son[1];
}
}
int Tree::kth(int x) {
node *now = rt;
while (1) {
if (now->son[0] != NULL && now->val > x) {
now = now->son[0];
continue;
}
if (now->son[0] != NULL) {
x -= now->son[0]->siz;
}
if (x <= now->rec) {
return now->val;
}
x -= now->rec;
now = now->son[1];
}
}
int Tree::pre(int x) {
node *now = rt;
int ans = -2147483647;
while (1) {
if (now->val >= x) {
if (now->son[0] != NULL) {
now = now->son[0];
continue;
} else {
return ans;
}
} else {
ans = max(ans, now->val);
if (now->son[1] == NULL) {
return ans;
} else {
now = now->son[1];
continue;
}
}
}
}
int Tree::nxt(int x) {
node *now = rt;
int ans = 2147483647;
while (1) {
if (now->val <= x) {
if (now->son[1] != NULL) {
now = now->son[1];
continue;
} else {
return ans;
}
} else {
ans = min(ans, now->val);
if (now->son[0] == NULL) {
return ans;
} else {
now = now->son[0];
continue;
}
}
}
}
int n, x, y;
int main() {
scanf("%d", &n);
while (n--) {
scanf("%d%d", &x, &y);
switch (x) {
case 1: {
printf("%d\n", tr.find(y));
break;
}
case 2: {
printf("%d\n", tr.kth(y));
break;
}
case 3: {
printf("%d\n", tr.pre(y));
break;
}
case 4: {
printf("%d\n", tr.nxt(y));
break;
}
case 5: {
tr.insert(y);
break;
}
default: {
break;
}
}
}
return 0;
}