Cod sursa(job #2642456)

Utilizator segtreapMihnea Andreescu segtreap Data 15 august 2020 13:28:41
Problema Secv8 Scor 85
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.76 kb
#include <cstdio>
#include <iostream>
#include <chrono>
#include <algorithm>
#include <random>

using namespace std;

mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());

struct treap {
  int val;
  int sz;
  int prio;
  treap* st;
  treap* dr;
  bool rev;
};

treap* empty_treap = new treap {
  0, /// val
  0, /// sz
  0, /// prio
  0, /// st
  0, /// dr
  0, /// rev
};

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;
  }
}

vector<int> priorities;

void build_priorities(int op) {
  op = min(op, 250000);
  for (int i = 1; i <= op; i++) {
    priorities.push_back(i);
  }
  shuffle(priorities.begin(), priorities.end(), rng);
}

treap* make(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(empty_treap, empty_treap);
  }
  if (pref <= a->st->sz) {
    auto p = split(a->st, pref);
    return make_pair(p.first, make(p.second, a, a->dr));
  } else {
    auto p = split(a->dr, pref - a->st->sz - 1);
    return make_pair(make(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 make(a->st, a, join(a->dr, b));
  } else {
    return make(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 access(treap* a, int p) {
  a = un_rev(a);
  if (p == a->st->sz + 1) {
    return a->val;
  }
  if (p <= a->st->sz) {
    return access(a->st, p);
  } else {
    return access(a->dr, p - a->st->sz - 1);
  }
}

treap* get_new(int val) {
  treap* sol = new treap {
    val, /// val
    1, /// sz
    priorities.back(), /// prio
    empty_treap, /// st
    empty_treap, /// dr
    0, /// rev
  };
  priorities.pop_back();
  return sol;
}

treap* ins(treap* a, int index, treap* val) {
  a = un_rev(a);
  if (a->sz == 0) {
    return val;
  }
  if (val->prio > a->prio) {
    auto p = split(a, index);
    return make(p.first, val, p.second);
  }
  if (index <= a->st->sz) {
    return make(ins(a->st, index, val), a, a->dr);
  } else {
    return make(a->st, a, ins(a->dr, index - a->st->sz - 1, val));
  }
}

treap* ins(treap* root, int index, int val) {
  treap* xo = get_new(val);
  return ins(root, index, xo);
}

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

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

treap *root = empty_treap;

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

int main() {
  freopen ("secv8.in", "r", stdin);
  freopen ("secv8.out", "w", stdout);
  int op, _;
  cin >> op >> _;
  build_priorities(op);
  for (int i = 1; i <= op; i++) {
    string s;
    cin >> s;
    if (s == "I") {
      int k, e;
      cin >> k >> e;
      k--;
      root = ins(root, k, e);
    }
    if (s == "A") {
      int k;
      cin >> k;
      cout << access(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();
  return 0;
}