Cod sursa(job #2599816)

Utilizator retrogradLucian Bicsi retrograd Data 11 aprilie 2020 19:16:36
Problema Secv8 Scor 85
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.18 kb
#include <bits/stdc++.h>

using namespace std;

struct SplayTree {
  struct Node {
    int p = 0, c[2] = {0, 0};
    int sz = 0, val;
    bool flip = 0;
    Node(int _val = -1) : val(_val) {}
  };
  vector<Node> T;
  int ref = 1;

  SplayTree() : T(3) {
    set(1, 1, 2);
    pull(1); pull(2);
  }

  // SPLAY TREE OPERATIONS START
  int dir(int x, int y) { return T[x].c[1] == y; }

  void set(int x, int d, int y) {
    if (x) {
      int& oy = T[x].c[d];
      if (T[oy].p == x) T[oy].p = 0;
      oy = y;
    }
    if (y) T[y].p = x;
  }

  void pull(int x) {
    if (!x) return;
    int &l = T[x].c[0], &r = T[x].c[1];
    T[x].sz = T[l].sz + T[r].sz + 1;
  }

  void push(int x) {
    if (!x || !T[x].flip) return;
    int &l = T[x].c[0], &r = T[x].c[1];
    swap(l, r); T[l].flip ^= 1; T[r].flip ^= 1;
    T[x].flip = 0;
  }

  int kth(int x, int k) {
    push(x);
    int lsz = T[T[x].c[0]].sz;
    if (k < lsz) return kth(T[x].c[0], k);
    if (k >= lsz + 1) return kth(T[x].c[1], k - lsz - 1);
    return x;
  }

  void rotate(int x, int d) { 
    int y = T[x].p, z = T[y].p, w = T[x].c[d];
    set(y, !d, w); 
    set(x, d, y);
    set(z, dir(z, y), x);
    pull(y);
  }

  void splay(int x) { 
    while (T[x].p) {
      int y = T[x].p, z = T[y].p;
      push(z); push(y); push(x);
      int dx = dir(y, x), dy = dir(z, y);
      if (!z) 
        rotate(x, !dx); 
      else if (dx == dy) 
        rotate(y, !dx), rotate(x, !dx); 
      else
        rotate(x, dy), rotate(x, dx);
    }
    pull(x);
  }


  int Split(int x) {
    splay(x);
    int ret = T[x].c[0];
    set(x, 0, 0);
    return ret;
  }

  int Join(int x, int y) {
    if (!x || !y) return x + y;
    splay(x); splay(y);
    while (true) {
      push(y);
      if (T[y].c[0]) y = T[y].c[0];
      else break;
    }
    splay(y);
    set(y, 0, x);
    return y;
  }

  void Insert(int k, int e) {
    int x = Access(k);
    int y = Split(x);
    int z = T.size();
    T.emplace_back(e);
    pull(z);
    ref = Join(Join(y, z), x);
  }
  
  int Access(int k) {
    splay(ref);
    if (k < 0 || k >= T[ref].sz) 
      return 0;
    int x = kth(ref, k);
    splay(x); return x;
  }

  void Reverse(int a, int b) {
    int x = Access(a), y = Access(b + 1);
    int l = Split(x), m = Split(y), r = y;
    T[m].flip ^= 1;
    ref = Join(Join(l, m), r);
  }

  void Delete(int a, int b) {
    int x = Access(a), y = Access(b + 1);
    x = Split(x); Split(y);
    ref = Join(x, y);
  }

  void Dump(ostream &cout, int _x = -1) {
    int x = _x;
    if (x == -1) x = ref;
    if (x == 0) return;
    push(x);
    Dump(cout, T[x].c[0]);
    if (x >= 3) cout << T[x].val << " ";
    Dump(cout, T[x].c[1]);
    if (_x == -1) cout << endl;
  }
};

int main() {
  ifstream cin("secv8.in");
  ofstream cout("secv8.out");
  SplayTree st;

  int q, c; cin >> q >> c;
  for (int i = 0; i < q; ++i) {
    char t; cin >> t;
    if (t == 'I') {
      int k, e; cin >> k >> e;
      st.Insert(k, e);
    }
    if (t == 'A') {
      int k; cin >> k;
      cout << st.T[st.Access(k)].val << '\n';
    }
    if (t == 'R') {
      int i, j; cin >> i >> j;
      st.Reverse(i, j);
    }
    if (t == 'D') {
      int i, j; cin >> i >> j;
      st.Delete(i, j);
    }
  }
  st.Dump(cout);
  
  return 0;
}