#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
using namespace std;
template <typename _Ty>
struct TreeNode
{
_Ty val; int nodes, repeatr;
TreeNode<_Ty> *left, *right, *parent;
TreeNode(_Ty x, TreeNode<_Ty>* left, TreeNode<_Ty>* right) : val(x), left(left), right(right)
{
if (left) left->parent = this;
if (right) right->parent = this;
nodes += (left->nodes + right->nodes + this->repeatr);
}
TreeNode(_Ty x, TreeNode<_Ty>* parent = nullptr, int repeats = 1) : val(x), parent(parent), repeatr(repeats)
{ left = right = nullptr; nodes = 1; }
bool is_leaf() { return !(this->left || this->right); }
};
template <typename _Ty>
class BinaryTree
{
protected:
TreeNode<_Ty> *root;
TreeNode<_Ty>* __constructBinaryTree(_Ty arr[], int &n);
TreeNode<_Ty>* constructBinaryTree(_Ty arr[])
{
int n = 0;
return __constructBinaryTree(arr, n);
}
void releaseBinaryTree(TreeNode<_Ty>* root);
public:
BinaryTree(_Ty arr[]) { root = constructBinaryTree(arr); root->parent = NULL; }
BinaryTree() { cout << "constructed\n"; root = NULL; }
~BinaryTree() { releaseBinaryTree(root); }
TreeNode<_Ty>* get_root() { return root; }
void traverse_pre (TreeNode<_Ty>* root, vector<_Ty>& alloc);
void traverse_in (TreeNode<_Ty>* root, vector<_Ty>& alloc);
void traverse_post (TreeNode<_Ty>* root, vector<_Ty>& alloc);
void traverse_layer (TreeNode<_Ty>* root, vector<_Ty>& alloc);
};
// construction & deconstruction
template<typename _Ty>
TreeNode<_Ty>* BinaryTree<_Ty>::__constructBinaryTree(_Ty arr[], int &n)
{
_Ty ch = arr[n]; n++;
if (ch == '#') return NULL;
return new TreeNode<_Ty>(ch, __constructBinaryTree(arr, n), __constructBinaryTree(arr, n));
}
template<class _Tp>
void BinaryTree<_Tp>::releaseBinaryTree(TreeNode<_Tp>* root)
{
if (root)
{
releaseBinaryTree(root->left);
releaseBinaryTree(root->right);
delete root;
}
}
template <typename _Tp>
class BinarySearchTree : virtual public BinaryTree<_Tp>
{
protected:
int tot_elements = 0;
const int __err_nullptr = 0x7fffffff;
const int __err_out_of_range = -__err_nullptr;
int __query_node_rank(TreeNode<_Tp>* node, _Tp value);
_Tp __find_nth_node (TreeNode<_Tp>* node, int value);
public:
int node_size(TreeNode<_Tp>* node) { return node ? node->nodes : 0; }
int normalize(TreeNode<_Tp>* p, int err_code) { return p ? p->val : err_code; }
BinarySearchTree() : BinaryTree<_Tp>() {}
int size() { return tot_elements; }
bool empty() { return size() == 0; }
// common tools
void add_node(_Tp value);
TreeNode<_Tp>* find_node(_Tp value)
{
TreeNode<_Tp>* node = this->root;
while (node && node->val != value) node = value < node->val ? node->left : node->right;
return node;
}
int query_node_rank (_Tp value) { return __query_node_rank (this->root, value) + 1; }
_Tp find_nth_node (int n) { return __find_nth_node (this->root, n); }
TreeNode<_Tp>* predecessor_of (TreeNode<_Tp>* node);
int predecessor_of (_Tp value) { return normalize(predecessor_of (find_node(value)), __err_nullptr); }
TreeNode<_Tp>* successor_of (TreeNode<_Tp>* node);
int successor_of (_Tp value) { return normalize(successor_of (find_node(value)), __err_out_of_range); }
// a few traverse functions
void traverse_layer (vector<_Tp>& alloc) { BinaryTree<_Tp>::traverse_layer (this->root, alloc); }
void traverse_pre (vector<_Tp>& alloc) { BinaryTree<_Tp>::traverse_pre (this->root, alloc); }
void traverse_in (vector<_Tp>& alloc) { BinaryTree<_Tp>::traverse_in (this->root, alloc); }
void traverse_post (vector<_Tp>& alloc) { BinaryTree<_Tp>::traverse_post (this->root, alloc); }
};
template <typename _Tp>
//void BinarySearchTree<_Tp>::add_node(TreeNode<_Tp>* root, _Tp value)
void BinarySearchTree<_Tp>::add_node(_Tp value)
{
if (!this->root)
this->root = new TreeNode<_Tp>(value);
else
{
int cmp = 0;
TreeNode<_Tp> *node = this->root, *parent = this->root;
while (node)
{
cmp = node->val - value; parent = node;
parent->nodes++;
if (cmp > 0) node = parent->left;
else if (cmp < 0) node = parent->right;
else { node->repeatr++; return; }
}
TreeNode<_Tp> *newNode = new TreeNode<_Tp>(value, parent);
cmp > 0 ? parent->left = newNode : parent->right = newNode;
}
tot_elements++;
return;
}
template <typename _Tp>
int BinarySearchTree<_Tp>::__query_node_rank(TreeNode<_Tp>* node, _Tp value)
{
try
{
if (!node) return 0;
int rank = node_size(node->left);
if (node->val == value) return rank;
if (node->val < value)
return __query_node_rank(node->right, value) + rank + node->repeatr;
else return __query_node_rank(node->left, value);
}
catch (const exception& e)
{
cout << e.what() << endl;
return __err_out_of_range;
}
}
template <typename _Tp>
_Tp BinarySearchTree<_Tp>::__find_nth_node(TreeNode<_Tp>* node, int value)
{
try
{
if (!node) return __err_nullptr;
int rank = node_size(node->left);
if (rank >= value)
return __find_nth_node(node->left, value);
if (rank + node->repeatr >= value) return node->val;
else return __find_nth_node(node->right, value - rank - node->repeatr);
}
catch (const exception& e)
{
cout << e.what() << endl;
return __err_nullptr;
}
}
template<typename _Tp>
TreeNode<_Tp>* BinarySearchTree<_Tp>::predecessor_of(TreeNode<_Tp>* node)
{
if (!node) return nullptr;
TreeNode<_Tp> *child = node->left;
if (child)
{
while (child->right) child = child->right;
return child;
}
else
{
TreeNode<_Tp> *parent = node;
while (parent->parent && parent == parent->parent->left) parent = parent->parent;
return parent->parent;
}
}
template <typename _Tp>
TreeNode<_Tp>* BinarySearchTree<_Tp>::successor_of(TreeNode<_Tp>* node)
{
if (!node) return nullptr;
TreeNode<_Tp> *child = node->right;
if (child)
{
while (child->left) child = child->left;
return child;
}
else
{
TreeNode<_Tp> *parent = node;
while (parent->parent && parent == parent->parent->right) parent = parent->parent;
return parent->parent;
}
}
#define BST BinarySearchTree
int main()
{
int n; cin >> n; vector<int> v;
BST<int> *bst = new BST<int>();
for (int i = 0; i < n; i++)
{
int op, x; cin >> op >> x;
switch (op)
{
case 1:
cout << bst->query_node_rank(x) << endl;
break;
case 2:
cout << bst->find_nth_node(x) << endl;
break;
case 3:
cout << bst->predecessor_of(x) << endl;
break;
case 4:
cout << bst->successor_of(x) << endl;
break;
case 5:
bst->add_node(x);
break;
}
}
delete bst;
return 0;
}
本地可以,交上去出现了 蜜 汁 错 误(