Cod sursa(job #2638659)

Utilizator segtreapMihnea Andreescu segtreap Data 29 iulie 2020 11:53:15
Problema Secv8 Scor 85
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.21 kb
#include <cstdio>
#include <iostream>
#include <random>
#include <chrono>
#include <algorithm>

using namespace std;

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

struct rip {
  int val;
  int sz;
  int priority;
  rip *first;
  rip *second;
  bool rev;
};

rip *empty_rrip = new rip {
  0, /// val
  0, /// sz
  0, /// priority
  0, /// first
  0, /// second
  0,/// rev
};

rip* un_rev(rip* root) {
  if (root->rev == 0) {
    return root;
  } else {
    root->rev = 0;
    swap(root->first, root->second);
    if (root->sz > 0) {
      root->first->rev ^= 1;
      root->second->rev ^= 1;
    }
    return root;
  }
}

void print(rip *root) {
  root = un_rev(root);
  if (root->sz == 0) {
    return;
  }
  print(root->first);
  cout << root->val << " ";
  print(root->second);
}

vector<int> priorities;

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

rip* make_rip(int val) {
  rip *sol = new rip {
    val, /// val
    1, /// sz
    priorities.back(), /// priority
    empty_rrip, /// first
    empty_rrip, /// second
    0,/// rev
  };
  priorities.pop_back();
  return sol;
}

rip* make_rip(rip *fi, rip *root, rip *se) {
  root->first = fi;
  root->second = se;
  root->sz = fi->sz + se->sz + 1;
  return root;
}

int access(rip* root, int k) {
  root = un_rev(root);
  if (k == root->first->sz + 1) {
    return root->val;
  }
  if (k <= root->first->sz) {
    return access(root->first, k);
  } else {
    return access(root->second, k - root->first->sz - 1);
  }
}

pair<rip*, rip*> split(rip *root, int pref_sz) {
  root = un_rev(root);
  if (root->sz == 0) {
    return make_pair(empty_rrip, empty_rrip);
  }
  if (pref_sz <= root->first->sz) {
    /// o sa fie in al doilea
    auto p = split(root->first, pref_sz);
    return make_pair(p.first, make_rip(p.second, root, root->second));
  } else {
    /// o sa fie in primul
    auto p = split(root->second, pref_sz - root->first->sz - 1);
    return make_pair(make_rip(root->first, root, p.first), p.second);
  }
}

///   7
/// 1   6

rip* join(rip *a, rip *b) {
  a = un_rev(a);
  b = un_rev(b);
  if (a->sz == 0) {
    return b;
  }
  if (b->sz == 0) {
    return a;
  }
  if (a->priority > b->priority) {
    return make_rip(a->first, a, join(a->second, b));
  } else {
    return make_rip(join(a, b->first), b, b->second);
  }
}

rip* ins(rip *root, int index, rip *val) {
  root = un_rev(root);
  if (root->sz == 0) {
    return val;
  }
  if (val->priority > root->priority) {
    auto p = split(root, index);
    return make_rip(p.first, val, p.second); /// ? question mark
  }
  if (index <= root->first->sz) {
    return make_rip(ins(root->first, index, val), root, root->second);
  }
  return make_rip(root->first, root, ins(root->second, index - root->first->sz - 1, val));
}

rip* ins(rip *root, int index, int val) {
  rip *nw = make_rip(val);
  return ins(root, index, nw);
}

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

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

rip *root = new rip {
  0, /// val
  0, /// sz
  0, /// priority
  0, /// first
  0, /// second
  0,/// rev
};

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);
  while (op--) {
    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;
}