From c1ee3d1930fb11a6c9fb0a2d864af23410fd3840 Mon Sep 17 00:00:00 2001 From: Matuush Date: Tue, 18 Mar 2025 16:26:54 +0100 Subject: [PATCH] Implemented treap operations without subtree-sizes --- file.hpp | 100 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 42 deletions(-) diff --git a/file.hpp b/file.hpp index 5832190..0c90cdd 100644 --- a/file.hpp +++ b/file.hpp @@ -3,55 +3,74 @@ #include using std::string; -typedef unsigned long long priority_type; -typedef unsigned long long key_type; +typedef unsigned long long count_type; #define RAND_MAX (1 << 62) class line; typedef std::pair two_lines; // Treap node representation of a line -class line { - priority_type priority; - key_type key; +struct line { + count_type priority, size; string text; line *left, *right; -public: - line(priority_type _p, string _t) : priority(_p), text(_t) {} - - two_lines split(string s) { return two_lines(nullptr, nullptr); } - void join(line *l) { - // Take minimum of priorities of roots - // Join subtrees - } - - line* find(key_type k) { - if(k < key) { - if(left != nullptr) - return left->find(k); - else - return nullptr; - } - else if(k > key) { - if(right != nullptr) - return right->find(k); - else - return nullptr; - } - else - return this; - } + line(count_type _p, string _t) : priority(_p), text(_t), size(-1), left(nullptr), right(nullptr) {} }; // Treap representation of a file -struct file { +class file { line* root; file() { srand(120); root = nullptr; } - void insert(string s) { + + // Split treap by k-th element + // TODO with sizes + two_lines split(line *l, count_type k) { + if(l == nullptr) return {nullptr, nullptr}; + + if(l->size <= k) { + auto two = split(l->right, k); + l->right = two.first; + return {l, two.second}; + } + else { + auto two = split(l->left, k - 1 - (l->left == nullptr ? 0 : l->left->size)); + l->left = two.second; + return {two.first, l}; + } + } + // Join two treaps + // TODO with sizes + line* join(line *a, line *b) { + if(a == nullptr) return b; + if(b == nullptr) return a; + + if(a->priority < b->priority) { + a->right = join(a->right, b); + return a; + } + else { + b->left = join(a, b->left); + return b; + } + } + line* join(two_lines two) { return join(two.first, two.second); } + +public: + line* find(line* l, count_type k) { + if(l == nullptr) return nullptr; + + if(k < l->size) + return find(l->left, k); + else if(k > l->size) + return find(l->right, k - 1 - (l->left == nullptr ? 0 : l->left->size) ); + else + return l; + } + void insert(int k, string s) { line *l = new line(rand(), s); if(root == nullptr) { @@ -59,16 +78,13 @@ struct file { return; } - auto two = root->split(s); - two.first->join(l); - two.first->join(two.second); + auto two = split(root, k); + join(two.first, l); + join(two); } - void remove(string s) { - auto two = root->split(s); - two.first = two.first->split(s).first; // TODO sharp split - two.first->join(two.second); - } - line* find(key_type k) { - return root->find(k); + void remove(count_type k) { + auto two = split(root, k); + two.first = split(two.first, k-1).first; + join(two); } };