Files
Roman Pytkov e154890897
Some checks failed
Build and Push Docker Images / build (src/LiquidCode.Tester.Gateway/Dockerfile, git.nullptr.top/liquidcode/liquidcode-tester-gateway-roman, gateway) (push) Successful in 1m12s
Build and Push Docker Images / build (src/LiquidCode.Tester.Worker/Dockerfile, git.nullptr.top/liquidcode/liquidcode-tester-worker-roman, worker) (push) Has been cancelled
Штуки
2025-11-02 19:31:34 +03:00

280 lines
7.9 KiB
C++

#include<bits/stdc++.h>
#ifndef KRAKOZYABRA
#include "testlib.h"
#else
#include "testliblochal.h"
#endif // KRAKOZYABRA
using namespace std;
template <typename T>
class ordered_set {
private:
struct Node {
T data;
int weight; // Number of nodes in the subtree rooted at this node
std::unique_ptr<Node> left;
std::unique_ptr<Node> right;
Node(const T& data) : data(data), weight(1), left(nullptr), right(nullptr) {}
};
std::unique_ptr<Node> 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<T>& 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<Node>(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<T> inorder_traversal() const {
std::vector<T> 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<int>(2), maxN = opt<int>(3);
int minM = opt<int>(4), maxM = opt<int>(5);
int minA = opt<int>(6), maxA = opt<int>(7);
int n = rnd.next(minN, maxN);
int m = rnd.next(minM, maxM);
cout << n << ' ' << m << '\n';
ordered_set<int> st;
vector<int> 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 = 1;
//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 <bits/stdc++.h>
//#include <random>
//
//using namespace std;
//
//random_device rd;
//mt19937 gen(rd());
//
//template <typename T>
//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;