Implemented treap operations without subtree-sizes
This commit is contained in:
parent
9525d3763a
commit
c1ee3d1930
1 changed files with 58 additions and 42 deletions
100
file.hpp
100
file.hpp
|
@ -3,55 +3,74 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
typedef unsigned long long priority_type;
|
typedef unsigned long long count_type;
|
||||||
typedef unsigned long long key_type;
|
|
||||||
#define RAND_MAX (1 << 62)
|
#define RAND_MAX (1 << 62)
|
||||||
class line;
|
class line;
|
||||||
typedef std::pair<line*, line*> two_lines;
|
typedef std::pair<line*, line*> two_lines;
|
||||||
|
|
||||||
// Treap node representation of a line
|
// Treap node representation of a line
|
||||||
class line {
|
struct line {
|
||||||
priority_type priority;
|
count_type priority, size;
|
||||||
key_type key;
|
|
||||||
string text;
|
string text;
|
||||||
line *left, *right;
|
line *left, *right;
|
||||||
|
|
||||||
public:
|
line(count_type _p, string _t) : priority(_p), text(_t), size(-1), left(nullptr), right(nullptr) {}
|
||||||
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;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Treap representation of a file
|
// Treap representation of a file
|
||||||
struct file {
|
class file {
|
||||||
line* root;
|
line* root;
|
||||||
|
|
||||||
file() {
|
file() {
|
||||||
srand(120);
|
srand(120);
|
||||||
root = nullptr;
|
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);
|
line *l = new line(rand(), s);
|
||||||
|
|
||||||
if(root == nullptr) {
|
if(root == nullptr) {
|
||||||
|
@ -59,16 +78,13 @@ struct file {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto two = root->split(s);
|
auto two = split(root, k);
|
||||||
two.first->join(l);
|
join(two.first, l);
|
||||||
two.first->join(two.second);
|
join(two);
|
||||||
}
|
}
|
||||||
void remove(string s) {
|
void remove(count_type k) {
|
||||||
auto two = root->split(s);
|
auto two = split(root, k);
|
||||||
two.first = two.first->split(s).first; // TODO sharp split
|
two.first = split(two.first, k-1).first;
|
||||||
two.first->join(two.second);
|
join(two);
|
||||||
}
|
|
||||||
line* find(key_type k) {
|
|
||||||
return root->find(k);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue