#include #include #include using std::string; typedef unsigned long long count_type; #define RAND_MAX (1 << 62) class line; typedef std::pair 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); } };