Cod sursa(job #2678260)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 28 noiembrie 2020 11:25:40
Problema Secv8 Scor 95
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.42 kb
#include <cstdio>
#include <chrono>
#include <random>
#include <iostream>
#include <algorithm>

using namespace std;

///mt19937 rng((long long) (new char));
mt19937 rng(0);
vector<int> randoms;

struct treap {
  int val;
  int sz;
  int prio;
  treap* st;
  treap* dr;
  bool rev; /// lazy for reverse
};


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

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

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

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

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

treap* join(treap* a, treap* b) {
  a = un_rev(a);
  b = un_rev(b);
  if (a->sz == 0) {
    return b;
  }
  if (b->sz == 0) {
    return a;
  }
  if (a->prio > b->prio) {
    return build(a->st, a, join(a->dr, b));
  } else {
    return build(join(a, b->st), b, b->dr);
  }
}


void print(treap *a) {
  a = un_rev(a);
  if (a->sz == 0) {
    return;
  }
  print(a->st);
  cout << a->val << " ";
  print(a->dr);
}

int get(treap* a, int k) {
  a = un_rev(a);
  if (k == a->st->sz + 1) {
    return a->val;
  }
  if (k <= a->st->sz) {
    return get(a->st, k);
  } else {
    return get(a->dr, k - a->st->sz - 1);
  }
}

treap* ins(treap* a, int pos, treap* val) {
  a = un_rev(a);
  if (a->sz == 0) {
    return val;
  }
  if (val->prio > a->prio) {
    auto p = split(a, pos);
    return build(p.first, val, p.second);
  }
  if (pos <= a->st->sz) {
    return build(ins(a->st, pos, val), a, a->dr);
  } else {
    return build(a->st, a, ins(a->dr, pos - a->st->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);
}

treap* root = gol;

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

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

  int q, _mifa;
  scanf("%d %d", &q, &_mifa);
  for (int i = 1; i <= min(q, 250000); i++) {
    randoms.push_back(i);
  }
  shuffle(randoms.begin(), randoms.end(), rng);
  for (int it = 1; it <= q; it++) {
    string s;
    cin >> s;
    if (s == "I") {
      int k, x;
      cin >> k >> x;
      root = ins(root, k - 1, x);
    }
    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();
}