#pragma warning(disable:4996)
#include <cstdio> #include <iostream> #include <cmath> using namespace std; struct AVL { int data; int height; int sum; int size; AVL* lch, * rch; }; const int Inf = 1e5; AVL* root = NULL; int GetHeight(AVL*); int GetBalance(AVL*); int GetSize(AVL*); void Update(AVL*); AVL* RotateLeft(AVL*); AVL* RotateRight(AVL*); AVL* RotateLeftRight(AVL*); AVL* RotateRightLeft(AVL*);
AVL* Insert(AVL*, int); AVL* Delte(AVL*, int, int); int GetRank(AVL*, int); AVL* FindByRank(AVL*, int); AVL* FindPre(AVL*, int); AVL* FindNext(AVL*, int); int main() { int n, op, x; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d%d", &op, &x); AVL* temp = NULL; if (op == 1)root = Insert(root, x); else if (op == 2)root = Delte(root, x, 1); else if (op == 3)printf("%d\n", GetRank(root, x)); else if (op == 4)temp = FindByRank(root, x); else if (op == 5)temp = FindPre(root, x); else if (op == 6)temp = FindNext(root, x); if (temp != NULL)printf("%d\n", temp->data); } return 0; } int GetHeight(AVL* root) { if (root == NULL)return 0; else return root->height; } int GetBalance(AVL* root) { if (root == NULL)return 0; else return GetHeight(root->lch) - GetHeight(root->rch); } int GetSize(AVL* root) { if (root == NULL)return 0; else return root->size; } void Update(AVL* root) { if (root == NULL)return; root->height = max(GetHeight(root->lch), GetHeight(root->rch)) + 1; root->size = GetSize(root->lch) + GetSize(root->rch) + root->sum; } AVL* RotateLeft(AVL* root) { AVL* temp = root->rch; root->rch = temp->lch; temp->lch = root;
Update(root); Update(temp); return temp; } AVL* RotateRight(AVL* root) { AVL* temp = root->lch; root->lch = temp->rch; temp->rch = root; Update(root); Update(temp); return temp; } AVL* RotateLeftRight(AVL* root) { root->lch = RotateLeft(root->lch); root = RotateRight(root); return root; } AVL* RotateRightLeft(AVL* root) { root->rch = RotateRight(root->rch); root = RotateLeft(root); return root; } AVL* Insert(AVL* root, int data) { if (root == NULL) { root = new AVL(); root->data = data; root->lch = NULL; root->rch = NULL; root->height = 1; root->sum = 1; root->size = 1; return root; } else if (data == root->data) { root->sum++; root->size++; return root; } else if (data < root->data) { root->lch = Insert(root->lch, data); Update(root); if (root != NULL && GetBalance(root) == 2) { if (GetBalance(root->lch) == -1) { root = RotateLeftRight(root); } else { root = RotateRight(root); } } } else { root->rch = Insert(root->rch, data); Update(root); if (root != NULL && GetBalance(root) == -2) { if (GetBalance(root->rch) == 1) { root = RotateRightLeft(root); } else { root = RotateLeft(root); } } } return root; }
AVL* Delte(AVL* root, int key, int delta) { if (root == NULL)return NULL; if (key < root->data) { root->lch = Delte(root->lch, key, delta); Update(root); if (root != NULL && GetBalance(root) == -2) { if (GetBalance(root->rch) == 1) { root = RotateRightLeft(root); } else { root = RotateLeft(root); } } return root; } else if (key > root->data) { root->rch = Delte(root->rch, key, delta); Update(root); if (root != NULL && GetBalance(root) == 2) { if (GetBalance(root->lch) == -1) { root = RotateLeftRight(root); } else { root = RotateRight(root); } } return root; } else { root->sum -= delta; root->size -= delta; if (root->sum > 0)return root; if (root->lch != NULL && root->rch != NULL) { AVL* temp = FindNext(root, key); root->data = temp->data; root->sum = temp->sum; root->rch = Delte(root->rch, temp->data, Inf); Update(root); if (root != NULL && GetBalance(root) == 2) { if (GetBalance(root->lch) == -1) { root = RotateLeftRight(root); } else { root = RotateRight(root); } } return root; } else { AVL* temp = root; if (root->lch == NULL)root = root->rch; else if (root->rch == NULL)root = root->lch; delete temp; Update(root); return root; } } } int GetRank(AVL* root, int key) { if (root == NULL)return 0; if (key == root->data) return GetSize(root->lch) + 1; else if (key > root->data) return GetSize(root->lch) + root->sum + GetRank(root->rch, key); else return GetRank(root->lch, key); } AVL* FindByRank(AVL* root, int rank) { if (rank > GetSize(root->lch) + root->sum) return FindByRank(root->rch, rank - GetSize(root->lch) - root->sum); else if (rank > GetSize(root->lch)) return root; else return FindByRank(root->lch, rank); } AVL* FindPre(AVL* root, int key) { AVL* ans = NULL; while (root != NULL) { if (key <= root->data) { root = root->lch; } else { if (ans == NULL || ans->data < root->data)ans = root; root = root->rch; } } return ans; } AVL* FindNext(AVL* root, int key) { AVL* ans = NULL; while (root != NULL) { if (key < root->data) { if (ans == NULL || ans->data > root->data)ans = root; root = root->lch; } else { root = root->rch; } } return ans; }
|