Cod sursa(job #3241714)

Utilizator LucaMuresanMuresan Luca Valentin LucaMuresan Data 2 septembrie 2024 23:15:04
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.15 kb
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#include <random>
#include <utility>
#warning That's not the baby, that's my baby

#define debug(x) #x << " = " << x << '\n'
typedef long long ll;

const int INF = 1e9;
std::mt19937 rng(1234);

struct Node {
  int key, prio;
  int size;
  bool rev;
  Node* l;
  Node* r;
  Node(int x = 0) : key(x), prio(rng()), size(1), rev(false), l(nullptr), r(nullptr) {} 
  
  void refresh() {
    size = 1 + (l != nullptr? l -> size : 0) + (r != nullptr? r -> size : 0);
  }
}; 

void push(Node* T) {
  if (T) {
    if (T -> rev) {
      std::swap(T -> l, T -> r);
      if (T -> l) {
        T -> l -> rev ^= 1;
      }
      if (T -> r) {
        T -> r -> rev ^= 1;
      }
      T -> rev = false;
    }
  }
}

Node* root = nullptr;

void split(Node* T, Node* &l, Node* &r, int x) {
  if (!T) {
    l = r = nullptr;
    return;
  } 
  push(T);
  int szL = 1 + (T -> l? T -> l -> size : 0);
  if (szL <= x) {
    split(T -> r, T -> r, r, x - szL);
    l = T;
  } else {
    split(T -> l, l, T -> l, x);
    r = T;
  }
  T -> refresh();
}
void merge(Node* &T, Node* l, Node* r) {
  if (!l || !r) {
    T = l? l : r;
    return;
  }
  push(l);
  push(r);
  if (l -> prio > r -> prio) {
    merge(l -> r, l -> r, r);
    T = l;
  } else {
    merge(r -> l, l, r -> l);
    T = r;
  }
  T -> refresh();
}
void insert(int key, int pos) {
  Node* l;
  Node* r;
  split(root, l, r, pos - 1);
  merge(root, l, new Node(key));
  merge(root, root, r);
}
void reverse(int l, int r) {
  Node *tl;
  Node *tmid;
  Node *tr;
  split(root, tl, root, l - 1);
  split(root, tmid, tr, r - l + 1); 
  tmid -> rev ^= 1;
  merge(root, tl, tmid);
  merge(root, root, tr);
}
void erase(int l, int r) {
  Node* tl;
  Node* tmid;
  Node* tr;
  split(root, tl, root, l - 1);
  split(root, tmid, tr, r - l + 1); 
  merge(root, tl, tr);
}
int acces(Node* T, int pos) { // am zis sa l fac pe asta mai legit
  push(T);
  push(T -> l);
  push(T -> r);
  int szL = T -> l? T -> l -> size : 0;
  if (pos <= szL) {
    return acces(T -> l, pos);
  } else if (pos == 1 + szL) {
    return T -> key;
  } else {
    return acces(T -> r, pos - szL - 1);
  }
}
void dfs(Node* T) {
  if (T) {
    push(T);
    dfs(T -> l);
    std::cout << T -> key << ' ';
    dfs(T -> r);
  }
}

int main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(0);
  std::cout.tie(0);
  #ifdef LOCAL
freopen("input.txt", "r", stdin);
  #else
freopen("secv8.in", "r", stdin);
freopen("secv8.out", "w", stdout);
  #endif
  
  int q, notsigma;
  std::cin >> q >> notsigma;

  while (q--) {
    char type;
    std::cin >> type;
    if (type == 'I') {
      int pos, x;
      std::cin >> pos >> x;
      insert(x, pos);
    } else if (type == 'A') {
      int pos;
      std::cin >> pos;
      std::cout << acces(root, pos) << '\n';
    } else if (type == 'R') {
      int l, r;
      std::cin >> l >> r;
      reverse(l, r);
    } else if (type == 'D') {
      int l, r;
      std::cin >> l >> r;
      erase(l, r);
    }
  }

  dfs(root);

  return 0;
}