Штуки
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
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
This commit is contained in:
276
exam-queue-17/files/gen2.cpp
Normal file
276
exam-queue-17/files/gen2.cpp
Normal file
@@ -0,0 +1,276 @@
|
||||
#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 = rnd.next(1, 2);
|
||||
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;
|
||||
Reference in New Issue
Block a user