Cod sursa(job #2824229)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 31 decembrie 2021 16:29:46
Problema Secv8 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.51 kb
#include <cstdio>
#include <iostream>
#include <random>
#include <chrono>
#include <cassert>
#include <algorithm>

using namespace std;

mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
vector<int> distribution(250000);

struct Node {
  int key;
  int value;
  int sz;
  bool reverseTag;
  Node* lft;
  Node* rgh;
  Node(int value) :
    key(distribution.back()),
    value(value),
    sz(1),
    reverseTag(false),
    lft(nullptr),
    rgh(nullptr) {
    assert(!distribution.empty());
  }
};

int getSize(Node* node) {
  if (!node) {
    return 0;
  }
  return node->sz;
}

Node* rebuild(Node* lft, Node* root, Node* rgh) {
  root->lft = lft;
  root->rgh = rgh;
  root->sz = getSize(lft) + 1 + getSize(rgh);
  return root;
}

Node* push(Node* node) {
  if (!getSize(node)) return node;
  if (node->reverseTag) {
    if (getSize(node->lft)) node->lft->reverseTag ^= 1;
    if (getSize(node->rgh)) node->rgh->reverseTag ^= 1;
    swap(node->lft, node->rgh);
    node->reverseTag = false;
  }
  return node;
}

pair<Node*, Node*> split(Node* node, int pref) {
  node = push(node);
  int nodeSize = getSize(node);
  assert(0 <= pref && pref <= nodeSize);
  if (pref == 0) {
    return make_pair(nullptr, node);
  }
  if (pref == nodeSize) {
    return make_pair(node, nullptr);
  }
  if (pref <= getSize(node->lft)) {
    auto it = split(node->lft, pref);
    return make_pair(it.first, rebuild(it.second, node, node->rgh));
  }
  auto it = split(node->rgh, pref - getSize(node->lft) - 1);
  return make_pair(rebuild(node->lft, node, it.first), it.second);
}

Node* join(Node* a, Node* b) {
  a = push(a);
  b = push(b);
  if (!getSize(a)) {
    return b;
  }
  if (!getSize(b)) {
    return a;
  }
  if (a->key > b->key) {
    return rebuild(a->lft, a, join(a->rgh, b));
  } else {
    return rebuild(join(a, b->lft), b, b->rgh);
  }
}

int get(Node* a, int pos) {
  a = push(a);
  assert(1 <= pos && pos <= getSize(a));
  int lftSize = getSize(a->lft);
  if (pos <= lftSize) {
    return get(a->lft, pos);
  }
  if (pos == lftSize + 1) {
    return a->value;
  }
  return get(a->rgh, pos - lftSize - 1);
}


Node* root;

void ins(int pos, int value) {
  Node* current = new Node(value);
  auto it = split(root, pos);
  root = join(join(it.first, current), it.second);
}

void print(Node* node) {
  if (!getSize(node)) return;
  print(node->lft);
  cout << node->value << " ";
  print(node->rgh);
}

void print() {
  print(root);
}

int main() {
  freopen ("secv8.in", "r", stdin);
  freopen ("secv8.out", "w", stdout);

  iota(distribution.begin(), distribution.end(), 0);
  shuffle(distribution.begin(), distribution.end(), rng);

  int q, _;
  cin >> q >> _;
  while (q--) {
    string s;
    cin >> s;
    if (s == "I") {
      int p, x;
      cin >> p >> x;
      ins(p - 1, x);
      continue;
    }
    if (s == "A") {
      int x;
      cin >> x;
      cout << get(root, x) << "\n";
      continue;
    }
    if (s == "R") {
      int l, r;
      cin >> l >> r;
      auto it = split(root, r);
      auto it2 = split(it.first, l - 1);
      it2.second->reverseTag ^= 1;
      root = join(join(it2.first, it2.second), it.second);
      continue;
    }
    if (s == "D") {
      int l, r;
      cin >> l >> r;
      auto it = split(root, r);
      auto it2 = split(it.first, l - 1);
      root = join(it2.first, it.second);
      continue;
    }
    assert(false);
  }
  print();

  return 0;
}