#include<stdio.h>
#pragma comment(linker, "/STACK:1073741824")
const int null = 0;
const int maxm = 100001;
int m_count; //表示当前在处理第几个操作。
/* 以下五个数组用来存splay 树。numNodes是附加信息:用来存子树的节点数,方便执行Get和Rank操作 */
int parent[maxm]; //父亲
int lchild[maxm]; //左孩子
int rchild[maxm]; //右孩子
int val[maxm]; //数据
int numNodes[maxm]; //以该点为根的结点个数
int splay[maxm]; //记录每次操作splay的次数.即输出的第2行。
int m, root = null, count = 0;//count为最新节点的序号。
inline void update(int x) { //更新结点数
numNodes[x] = numNodes[lchild[x]] + numNodes[rchild[x]] + 1;
}
void splayTree(int x) {
int f = parent[x];
if (f == null) return;
splay[m_count]++; //第m_count次的splay的次数
int g = parent[f];
if (g == null) { /*zig or zag*/
if (lchild[f] == x) { /*zig*/
if(rchild[x]!=null){
lchild[f] = rchild[x];
parent[rchild[x]] = f;
}
else {
lchild[f]=null;
}
rchild[x] = f;
parent[f]=x;
}
else { /*zag*/
if(lchild[x]!=null){
rchild[f] = lchild[x];
parent[lchild[x]] = f;
}
else {
rchild[f]=null;
}
lchild[x] = f;
parent[f]=x;
}
update(f); update(x);
parent[x] = null; root = x;
return;
}
int h=parent[g];
if (lchild[g] == f && lchild[f] == x) { /*zig-zig*/
if(rchild[f]!=null){
lchild[g] = rchild[f];
parent[rchild[f]] = g;
}
else {
lchild[g] =null;
}
rchild[f] = g;
parent[g]=f;
if (rchild[x] != null) {
lchild[f]=rchild[x];
parent[rchild[x]]=f;
}
else {
lchild[f]=NULL;
}
rchild[x]=f;
parent[f]=x;
}
else if (rchild[g] == f && rchild[f] == x) { /*zag-zag*/
if(lchild[f]!=null){
rchild[g] = lchild[f];
parent[lchild[f]] = g;
}
else {
rchild[g] =null;
}
lchild[f] = g;
parent[g]=f;
if (lchild[x] != null) {
rchild[f]=lchild[x];
parent[lchild[x]]=f;
}
else {
rchild[f]=NULL;
}
lchild[x]=f;
parent[f]=x;
}
else if (lchild[g] == f && rchild[f] == x) { /*zig-zag*/
if(lchild[x]!=null){
rchild[f]=lchild[x];
parent[lchild[x]]=f;
}
else {
rchild[f]=null;
}
lchild[x]=f;
parent[f]=x;
if(rchild[x]!=null){
lchild[g]=rchild[x];
parent[rchild[x]]=g;
}
else {
lchild[g]=null;
}
rchild[x]=g;
parent[g]=x;
}
else if (rchild[g] == f && lchild[f] == x) { /*zag-zig*/
if(rchild[x]!=null){
lchild[f]=rchild[x];
parent[rchild[x]]=f;
}
else {
lchild[f]=null;
}
rchild[x]=f;
parent[f]=x;
if(lchild[x]!=null){
rchild[g]=rchild[x];
parent[lchild[x]]=g;
}
else {
rchild[g]=null;
}
lchild[x]=g;
parent[g]=x;
}
update(g); update(f); update(x);
if (h == null) {
root = x; parent[root] = null; //更新根节点
}
else{
parent[x] = h;
if (val[x] < val[h]) lchild[h] = x;
else {
rchild[h] = x;
}
splayTree(x);
}
}
int search(int x){ //调用search时确保root!=null
int p = root;
while (val[p] != x) {
if (x < val[p]){
p = lchild[p];
}
else{
p = rchild[p];
}
}
return p;
}
void Insert(int x) {
count++; numNodes[count]++;
val[count] = x; //创建结点,count为其索引
lchild[count] = rchild[count] = null;
if (root == null) { //根节点为空
root = count; parent[root] = null;
}
else {
int p = root;
while (true) {
if (x < val[p]) {
if (lchild[p] == null) {
lchild[p] = count;
break;
} else {
p = lchild[p];
}
} else {
if (rchild[p] == null) {
rchild[p] = count;
break;
} else {
p = rchild[p];
}
}
}
parent[count] = p;
splayTree(count);
}
}
void Delete(int p){
if (lchild[p] != null && rchild[p] != null) { //待删除节点2个孩子
int s = lchild[p];
while (rchild[s] != null) s = rchild[s];
//add sth here. //此时待删除节点变为了s。f仍然是p的父亲。 p只有<=1个孩子了。
if (lchild[s] != null) {
parent[lchild[s]] = p; // 将s的左子树的父亲指向p
lchild[p] = lchild[s]; // 将p的左子树改为s的左子树
}
// 删除节点s
if (s != lchild[p]) {
parent[rchild[s]] = s; // 如果s不是p的左孩子,则把s的右子树接到s的父节点
rchild[s] = rchild[p]; // 将p的右子树挂到s上
}
// 删除节点p之后,s变为新的p,并且做相应的旋转调整
splayTree(s);
return;
}
int f = parent[p], s = lchild[p] != null ? lchild[p] : rchild[p]; // s是空或是p的唯一的孩子孩子
if (f == null) { /*删除的节点p是根节点*/
root = s; parent[root] = null;
}
else{
if (lchild[f] == p) {
lchild[f] = s; // 将父节点的左子树指向s
} else {
rchild[f] = s; // 将父节点的右子树指向s
}
if (s != null) {
parent[s] = f; // 将s的父亲设置为f
}
}
splayTree(s);
}
int Rank(int x) {
int q = root;
int cnt = 0;
while (true) {
int n = numNodes[lchild[q]];
if (x > val[q]) {
cnt += n + 1;
q = rchild[q];
}
else if (x < val[q])
q = lchild[q];
else{
cnt += n + 1;
break;
}
}
}
int Get(int k) {//找第k小的数
int q = root;
while (true) {
int n = numNodes[lchild[q]];
if (k > n + 1) {
k -= n + 1;
q = rchild[q];
}
else if (k <= n) {
q = lchild[q];
}
else {
return val[q];
}
}
}
int result[maxm];
int main() {
int kind, x, t_rank_get = 0;//kind表示操作类型 x表示操作参数
scanf("%d", &m);
for (m_count = 1; m_count <= m; m_count++) {
scanf("%d %d", &kind, &x);
if (1 == kind) Insert(x);
else if (2 == kind) Delete(search(x));
else if (3 == kind) result[++t_rank_get] = Rank(x);
else result[++t_rank_get] = Get(x);
}
for (int i = 1; i <= t_rank_get; i++) printf("%d ", result[i]);
printf("\n");
for (int i = 1; i <= m; i++) printf("%d ", splay[i]);
return 0;
}
预计输入:
10
1 1
1 2
1 3
1 4
1 5
1 6
2 1
3 3
4 5
2 5
输出:
2 6
0 1 1 1 1 1 2 1 1 0
但是上述代码输出:
3 5
0 1 1 1 1 1 0 0 0 1
该代码有什么逻辑问题?