Cod sursa(job #2744502)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 24 aprilie 2021 19:32:53
Problema Secv8 Scor 25
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.72 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#include <cassert>
#include <chrono>
#include <random>

using namespace std;

mt19937 rng((long long) (new char));
vector<int> smn;

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

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

node* push(node* a) {
  if (!sz(a)) {
    return 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;
  }
  return a;
}

node* root;
node* nothing;

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

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

node* join(node* a, node* b) {
  a = push(a);
  b = 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* val) {
  assert(1 <= k && k <= sz(a) + 1);
 // assert(a != a->lft);
 // assert(a != a->rgh);
  if (sz(a)) {
    assert(a != a->lft);
    assert(a != a->rgh);
  }
  a = push(a);
 // cout << "aici\n";
  if (sz(a) == 0) {
   // cout << "kek\n";
    return val;
  }
  if (val->key > a->key) {
    auto p = split(a, k - 1);
    return build(p.first, val, p.second);
  }
  if (k <= sz(a->lft) + 1) {
    return build(ins(a->lft, k, val), a, a->rgh);
  } else {
    return build(a->lft, a, ins(a->rgh, k - sz(a->lft) - 1, val));
  }
}

void ins(int k, int x) {
  node* b = new node;
  b->key = smn.back();
  smn.pop_back();
  b->sz = 1;
  b->val = x;
  root = ins(root, k, b);
}

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

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

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

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

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

  int lol = 3;
  for (int i = 1; i <= q; i++) {
    string s;
    cin >> s;
    if (s == "I") {
      int k, x;
      cin >> k >> x;
      ins(k, x);
    }
    if (s == "A") {
      int k;
      cin >> k;
      cout << get(root, k) << "\n";
    }
    if (s == "R") {
      int l, r;
      cin >> l >> r;
      auto p = split(root, r);
      auto p2 = split(p.first, l - 1);
      p2.second->inv ^= 1;
      root = join(join(p2.first, p2.second), p.second);
    }
    if (s == "D") {
      int l, r;
      cin >> l >> r;
      auto p = split(root, r);
      auto p2 = split(p.first, l - 1);
      root = join(p2.first, p.second);
    }
   // print();
  }
  print();
  return 0;
}