Cod sursa(job #2695384)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 12 ianuarie 2021 19:50:16
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.36 kb
#include <cstdio>
#include <iostream>
#include <random>
#include <algorithm>

using namespace std;

mt19937 rng(1);
int q, any_reverse_operations, max_possible_insert_operations;
vector<int> some_random_numbers;

struct treap {
  int sz;
  int x;
  int prio;
  bool rev;
  treap* l;
  treap* r;
};

treap* gol = new treap {0, 0, 0, 0, 0, 0};
treap* root = gol;

treap* single(int val) {
  treap* ret = new treap {1, val, some_random_numbers.back(), 0, gol, gol};
  some_random_numbers.pop_back();
  return ret;
}

treap* un_rev(treap* a) {
  if (a->rev) {
    swap(a->l, a->r);
    if (a->sz) {
      a->l->rev ^= 1;
      a->r->rev ^= 1;
    }
    a->rev = 0;
  }
  return a;
}

treap* build(treap* l, treap* a, treap* r) {
  a->sz = l->sz + r->sz + 1;
  a->l = l;
  a->r = r;
  return a;
}

pair<treap*, treap*> split(treap* a, int pref) {
  a = un_rev(a);
  if (!a->sz) {
    return {gol, gol};
  }
  if (pref <= a->l->sz) {
    auto p = split(a->l, pref);
    return make_pair(p.first, build(p.second, a, a->r));
  } else {
    auto p = split(a->r, pref - a->l->sz - 1);
    return make_pair(build(a->l, a, p.first), p.second);
  }
}

treap* join(treap* a, treap* b) {
  a = un_rev(a);
  b = un_rev(b);
  if (!a->sz) {
    return b;
  }
  if (!b->sz) {
    return a;
  }
  if (a->prio > b->prio) {
    return build(a->l, a, join(a->r, b));
  } else {
    return build(join(a, b->l), b, b->r);
  }
}

void print(treap* a) {
  a = un_rev(a);
  if (!a->sz) {
    return;
  }
  print(a->l);
  cout << a->x << " ";
  print(a->r);
}

int get(treap* a, int k) {
  a = un_rev(a);
  if (k == a->l->sz + 1) {
    return a->x;
  }
  if (k <= a->l->sz) {
    return get(a->l, k);
  } else {
    return get(a->r, k - a->l->sz - 1);
  }
}

treap* ins(treap* a, int pos, treap* val) {

  a = un_rev(a);
  if (!a->sz) {
    return val;
  }
  if (val->prio > a->prio) {
    auto p = split(a, pos - 1);
    return build(p.first, val, p.second);
  }
  if (pos <= a->l->sz + 1) {
    return build(ins(a->l, pos, val), a, a->r);
  } else {
    return build(a->l, a, ins(a->r, pos - a->l->sz - 1, val));
  }
}

treap* ins(treap* a, int pos, int val) {
  return ins(a, pos, single(val));
}

treap* del(treap* a, int l, int r) {
  auto p = split(a, r);
  auto p2 = split(p.first, l - 1);
  return join(p2.first, p.second);
}

treap* rev(treap* a, int l, int r) {
  auto p = split(a, r);
  auto p2 = split(p.first, l - 1);
  p2.second->rev ^= 1;
  return join(join(p2.first, p2.second), p.second);
}

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

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

  cin >> q >> any_reverse_operations;
  max_possible_insert_operations = min(q, 250000);
  some_random_numbers.resize(max_possible_insert_operations);
  iota(some_random_numbers.begin(), some_random_numbers.end(), 0);

  while (q--) {
    string s;
    cin >> s;
    if (s == "I") {
      int k, e;
      cin >> k >> e;
      root = ins(root, k, e);
    }
    if (s == "A") {
      int k;
      cin >> k;
      cout << get(root, k) << "\n";
    }
    if (s == "R") {
      int l, r;
      cin >> l >> r;
      root = rev(root, l, r);
    }
    if (s == "D") {
      int l, r;
      cin >> l >> r;
      root = del(root, l, r);
    }
  }
  print();

}