Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdlib>
- #include <ctime>
- #include <vector>
- #include <string>
- using namespace std;
- struct TreapElement {
- TreapElement(TreapElement *left, TreapElement *right, int cost, int y, int count)
- : left(left), right(right), cost(cost), y(y), count(count) {
- root = nullptr;
- hasEmptyVertex = false;
- }
- TreapElement() {
- root = nullptr;
- left = nullptr;
- right = nullptr;
- }
- virtual ~TreapElement() = default;
- TreapElement *left, *right, *root;
- int y, count, cost;
- bool hasEmptyVertex;
- };
- void updateV(TreapElement *v) {
- if (v != nullptr) {
- v->count = (v->left == nullptr ? 0 : v->left->count) + (v->right == nullptr ? 0 : v->right->count) + 1;
- v->hasEmptyVertex = (v->cost == 0
- || (v->left != nullptr && v->left->hasEmptyVertex)
- || (v->right != nullptr && v->right->hasEmptyVertex));
- }
- }
- TreapElement **split(TreapElement *v, int pseudoKey) {
- TreapElement *leftTreap = nullptr;
- TreapElement *rightTreap = nullptr;
- TreapElement *middleTreap = nullptr;
- auto **tempTreaps = new TreapElement*[2];
- if (v == nullptr) {
- tempTreaps[0] = nullptr;
- tempTreaps[1] = nullptr;
- return tempTreaps;
- }
- int currentIndex = (v->left != nullptr ? v->left->count : 0) + 1;
- if (pseudoKey >= currentIndex) {
- if (v->right == nullptr) {
- rightTreap = nullptr;
- } else {
- tempTreaps = split(v->right, pseudoKey - currentIndex);
- middleTreap = tempTreaps[0];
- rightTreap = tempTreaps[1];
- }
- leftTreap = new TreapElement(v->left, middleTreap, v->cost, v->y, v->count);
- updateV(leftTreap);
- } else {
- if (v->left == nullptr) {
- leftTreap = nullptr;
- } else {
- tempTreaps = split(v->left, pseudoKey);
- leftTreap = tempTreaps[0];
- middleTreap = tempTreaps[1];
- }
- rightTreap = new TreapElement(middleTreap, v->right, v->cost, v->y, v->count);
- updateV(rightTreap);
- }
- tempTreaps[0] = leftTreap;
- tempTreaps[1] = rightTreap;
- return tempTreaps;
- }
- TreapElement *merge(TreapElement *leftTreap, TreapElement *rightTreap) {
- if (leftTreap == nullptr) {
- updateV(rightTreap);
- return rightTreap;
- }
- if (rightTreap == nullptr) {
- updateV(leftTreap);
- return leftTreap;
- }
- if (leftTreap->y > rightTreap->y) {
- leftTreap->right = merge(leftTreap->right, rightTreap);
- updateV(leftTreap);
- return leftTreap;
- } else {
- rightTreap->left = merge(leftTreap, rightTreap->left);
- updateV(rightTreap);
- return rightTreap;
- }
- }
- TreapElement *insert(TreapElement *v, int position, int cost, int value) {
- TreapElement **tempTreaps = split(v, position);
- auto *middleTreap = new TreapElement(nullptr, nullptr, cost, value, 1);
- return merge(merge(tempTreaps[0], middleTreap), tempTreaps[1]);
- }
- TreapElement *remove(TreapElement *v, int position) {
- TreapElement **tempTreapsOne = split(v, position);
- TreapElement **tempTreapsTwo = split(tempTreapsOne[1], 1);
- return merge(tempTreapsOne[0], tempTreapsTwo[1]);
- }
- int findEmptyVertexWithLowestPosition(TreapElement *v, int position) {
- if (v->left != nullptr && v->left->hasEmptyVertex) {
- return findEmptyVertexWithLowestPosition(v->left, position);
- } else if (v->cost == 0) {
- return position + (v->left != nullptr ? v->left->count : 0);
- } else {
- return findEmptyVertexWithLowestPosition(v->right, position + (v->left != nullptr ? v->left->count : 0) + 1);
- }
- }
- vector<int> costs;
- void inOrderTraversal(TreapElement *v) {
- if (v != nullptr) {
- inOrderTraversal(v->left);
- costs.insert(costs.begin(), v->cost);
- inOrderTraversal(v->right);
- }
- }
- int main() {
- int n, m;
- cin >> n >> m;
- auto treap = new TreapElement();
- srand(time(nullptr));
- for (int i = 0; i <= n + m; ++i) {
- treap->root = insert(treap->root, i, 0, rand());
- }
- for (int i = 0; i < n; ++i) {
- int x;
- cin >> x;
- x -= 1;
- treap->root = insert(treap->root, x, i + 1, rand());
- TreapElement **tempTreaps = split(treap->root, ++x);
- int position = findEmptyVertexWithLowestPosition(tempTreaps[1], x);
- treap->root = remove(treap->root, position);
- }
- inOrderTraversal(treap->root);
- int i = 0;
- while (costs[i] == 0) {
- costs.erase(costs.begin());
- }
- string result;
- cout << costs.size() << endl;
- while (costs.size() > 1) {
- result = " " + to_string(costs[0]) + result;
- costs.erase(costs.begin());
- }
- result = to_string(costs[0]) + result;
- cout << result;
- delete treap;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement