zeed/file.hpp

90 lines
1.8 KiB
C++

#include <string>
#include <cstdlib>
#include <utility>
using std::string;
typedef unsigned long long count_type;
#define RAND_MAX (1 << 62)
class line;
typedef std::pair<line*, line*> two_lines;
// Treap node representation of a line
struct line {
count_type priority, size;
string text;
line *left, *right;
line(count_type _p, string _t) : priority(_p), text(_t), size(-1), left(nullptr), right(nullptr) {}
};
// Treap representation of a file
class file {
line* root;
file() {
srand(120);
root = nullptr;
}
// 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) {
root = l;
return;
}
auto two = split(root, k);
join(two.first, l);
join(two);
}
void remove(count_type k) {
auto two = split(root, k);
two.first = split(two.first, k-1).first;
join(two);
}
};