Cod sursa(job #2743776)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 23 aprilie 2021 15:02:06
Problema Secv8 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.48 kb
#include <cstdio>
#include <vector>
#include <iostream>
#include <random>
#include <algorithm>
#include <cassert>

using namespace std;

mt19937 rng(0);
vector<int> randoms;

struct node {
  int key;
  int val;
  int sz;
  int inv;
  node* lft;
  node* rgh;
  node() {
    key = 0;
    val = 0;
    sz = 0;
    inv = 0;

    lft = 0;
    rgh = 0;
  }
};

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

void push(node*& a) {
  if (sz(a)) {
    if (a->inv) {
      swap(a->lft, a->rgh);
      if (sz(a->lft)) {
        a->lft->inv ^= 1;
      }
      if (sz(a->rgh)) {
        a->rgh->inv ^= 1;
      }
      a->inv = 0;
    }
  }
}

node* root;
node* nothing;

void print(node* a) {
  push(a);
  if (!sz(a)) {
    return;
  }
  print(a->lft);
  cout << a->val << " ";
  print(a->rgh);
}

void print() {
  print(root);
  cout << "\n";
}

int get(node* a, int k) {
  push(a);
  assert(1 <= k && k <= sz(a));
  if (k <= sz(a->lft)) {
    return get(a->lft, k);
  }
  if (k == sz(a->lft) + 1) {
    return a->val;
  }
  return get(a->rgh, k - sz(a->lft) - 1);
}

node* build(node* lft, node* a, node* rgh) {
  assert(a);
  a->sz = sz(lft) + sz(rgh) + 1;
  a->lft = lft;
  a->rgh = rgh;
  return a;
}

pair<node*, node*> split(node* a, int pre) {
  push(a);
  assert(0 <= pre && pre <= sz(a));
  if (!pre) {
    return make_pair(nothing, a);
  }
  if (pre == sz(a)) {
    return make_pair(a, nothing);
  }
  if (pre <= sz(a->lft)) {
    auto p = split(a->lft, pre);
    return make_pair(p.first, build(p.second, a, a->rgh));
  } else {
    auto p = split(a->rgh, pre - sz(a->lft) - 1);
    return make_pair(build(a->lft, a, p.first), p.second);
  }
}

node* join(node* a, node* b) {
  push(a);
  push(b);
  if (!sz(a)) {
    return b;
  }
  if (!sz(b)) {
    return a;
  }
  if (a->key > b->key) {
    return build(a->lft, a, join(a->rgh, b));
  } else {
    return build(join(a, b->lft), b, b->rgh);
  }
}

node* ins(node* a, int k, node* b) {
  push(a);
  assert(1 <= k && k <= sz(a) + 1);
  if (!sz(a)) {
    return b;
  }
  if (b->key > a->key) {
    auto p = split(a, k - 1);
    return build(p.first, b, p.second);
  }
  if (k <= sz(a->lft) + 1) {
    return build(ins(a->lft, k, b), a, a->rgh);
  } else {
    return build(a->lft, a, ins(a->rgh, k - sz(a->lft) - 1, b));
  }
}

void ins(int k, int b) {
  node* nodb = new node;
  nodb->sz = 1;
  assert(!randoms.empty());
  nodb->key = randoms.back();
  randoms.pop_back();
  nodb->val = b;
  root = ins(root, k, nodb);
}

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

  int q, ___;
  cin >> q >> ___;
  randoms.resize(min(250000, q));
  iota(randoms.begin(), randoms.end(), 1);
  shuffle(randoms.begin(), randoms.end(), rng);

  while (q--) {
    string s;
    cin >> s;
    if (s == "I") {
      int k, b;
      cin >> k >> b;
      ins(k, b);
    }
    if (s == "A") {
      int k;
      cin >> k;
      cout << get(root, k) << "\n";
    }
    if (s == "R") {
      int l, r;
      cin >> l >> r;
      auto p1 = split(root, r);
      auto p2 = split(root, l - 1);
      p2.second->inv ^= 1;
      root = join(join(p2.first, p2.second), p1.second);
    }
    if (s == "D") {
      int l, r;
      cin >> l >> r;
      auto p1 = split(root, r);
      auto p2 = split(root, l - 1);
      root = join(p2.first, p1.second);
    }
  }
  print(root);
}