#include #ifndef KRAKOZYABRA #include "testlib.h" #else #include "testliblochal.h" #endif // KRAKOZYABRA using namespace std; template class ordered_set { private: struct Node { T data; int weight; // Number of nodes in the subtree rooted at this node std::unique_ptr left; std::unique_ptr right; Node(const T& data) : data(data), weight(1), left(nullptr), right(nullptr) {} }; std::unique_ptr root; // Helper function to update the weight of a node void update_weight(Node* node) { if (node) { node->weight = 1; if (node->left) node->weight += node->left->weight; if (node->right) node->weight += node->right->weight; } } // Helper function for insertion Node* insert_recursive(Node* node, const T& data) { if (!node) { return new Node(data); } if (data < node->data) { node->left.reset(insert_recursive(node->left.release(), data)); //Release ownership before recursive call } else { node->right.reset(insert_recursive(node->right.release(), data)); //Release ownership before recursive call } update_weight(node); return node; } // Helper function for deletion (find minimum in right subtree) Node* find_min(Node* node) { while (node->left) { node = node->left.get(); // Access the raw pointer } return node; } // Helper function for deletion Node* delete_recursive(Node* node, const T& data) { if (!node) { return nullptr; // Value not found } if (data < node->data) { node->left.reset(delete_recursive(node->left.release(), data)); //Release ownership before recursive call } else if (data > node->data) { node->right.reset(delete_recursive(node->right.release(), data)); //Release ownership before recursive call } else { // Node to be deleted found // Case 1: Node with no child or only one child if (!node->left) { Node* temp = node->right.release(); delete node; return temp; } else if (!node->right) { Node* temp = node->left.release(); delete node; return temp; } // Case 2: Node with two children Node* temp = find_min(node->right.get()); node->data = temp->data; node->right.reset(delete_recursive(node->right.release(), temp->data)); } update_weight(node); return node; } //Helper for get_element_at_index (find the k-th smallest element). T get_element_at_index_recursive(Node* node, int index) { if (!node) { throw std::out_of_range("Index out of range"); } int left_subtree_size = (node->left) ? node->left->weight : 0; if (index == left_subtree_size) { return node->data; } else if (index < left_subtree_size) { return get_element_at_index_recursive(node->left.get(), index); } else { return get_element_at_index_recursive(node->right.get(), index - left_subtree_size - 1); } } //Helper to perform inorder traversal void inorder_traversal_recursive(Node* node, std::vector& result) const { if (node) { inorder_traversal_recursive(node->left.get(), result); result.push_back(node->data); inorder_traversal_recursive(node->right.get(), result); } } //Helper to find index of an element. int get_index_of_element_recursive(Node* node, const T& target, int current_rank) const { if (!node) { return -1; // Element not found } int left_subtree_size = (node->left) ? node->left->weight : 0; if (target == node->data) { return current_rank + left_subtree_size; } else if (target < node->data) { return get_index_of_element_recursive(node->left.get(), target, current_rank); } else { return get_index_of_element_recursive(node->right.get(), target, current_rank + left_subtree_size + 1); } } public: ordered_set() : root(nullptr) {} void insert(const T& data) { if (!root) { root = std::make_unique(data); } else { root.reset(insert_recursive(root.release(), data)); //Release ownership before recursive call } } void erase(const T& data) { root.reset(delete_recursive(root.release(), data)); //Release ownership before recursive call } T get_element(int index) { if (index < 0 || index >= size()) { throw std::out_of_range("Index out of range"); } return get_element_at_index_recursive(root.get(), index); } int size() const { return (root) ? root->weight : 0; } bool empty() const { return root == nullptr; } void clear() { root.reset(); // Effectively deletes the entire tree } // Returns a vector of the elements in sorted order (inorder traversal) std::vector inorder_traversal() const { std::vector result; inorder_traversal_recursive(root.get(), result); return result; } // Added function to get the index of an element int get_index(const T target) const { return get_index_of_element_recursive(root.get(), target, 0); } }; int main(int argc, char* argv[]) { #ifndef KRAKOZYABRA registerGen(argc, argv, 1); #endif // KRAKOZYABRA int minN = opt(2), maxN = opt(3); int minM = opt(4), maxM = opt(5); int minA = opt(6), maxA = opt(7); int n = rnd.next(minN, maxN); int m = rnd.next(minM, maxM); cout << n << ' ' << m << '\n'; ordered_set st; vector a; while (a.size() < n) { int aa = rnd.next(minA, maxA); if (st.get_index(aa) == -1) { a.push_back(aa); st.insert(aa); } } auto getrndin = [&]() { if (st.size() == 0) return -1; int sz = st.size(); int i = rnd.next(0, sz - 1); return st.get_element(i); }; auto getrndnew = [&]() { int aa = rnd.next(minA, maxA); while (st.get_index(aa) != -1) aa = rnd.next(minA, maxA); return aa; }; for (int i = 0; i < n; i++) cout << a[i] << " \n"[i == n - 1]; for (int i = 0; i < m; i++) { int t = 0; if (st.size() == 0) t = 2; else t = rnd.next(1, 3); if (t == 1) { int x = getrndnew(); int y = getrndin(); st.insert(x); cout << t << ' ' << x << ' ' << y << '\n'; } if (t == 2) { int x = getrndnew(); st.insert(x); cout << t << ' ' << x << '\n'; } if (t == 3) { int x = getrndin(); st.erase(x); cout << t << ' ' << x << '\n'; } } } //#pragma once //#include //#include //#include // //using namespace std; // //random_device rd; //mt19937 gen(rd()); // //template //T opt(T value) { // FILE* stream; // freopen_s(&stream, "params.txt", "r", stdin); // T res; // for (int i = 0; i < value; i++) // cin >> res; // return res; //} // //class Random { //public: // long long next(long long a, long long b) { // return a + gen() % (b - a + 1); // }; //}; // //Random rnd;