Cod sursa(job #1985166)

Utilizator MiricaMateiMirica Matei MiricaMatei Data 27 mai 2017 00:29:31
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.3 kb
#include <cstdio>
#include <ctime>
#include <algorithm>

using namespace std;

struct Node {
  int val;
  int sz;
  long long priority;
  Node* left;
  Node* right;
  bool reversed;
};

struct Answer {
  Node* first;
  Node* second;
};

Node* emptyNode = new Node{0, 0, -1, NULL, NULL, false};

void unreverse(Node* root) {
  if (root != emptyNode && root->reversed == true) {
    swap(root->left, root->right);
    root->left->reversed = !root->left->reversed;
    root->right->reversed = !root->right->reversed;
    root->reversed = false;
  }
}

void recompute(Node* root) {
  root->sz = root->left->sz + 1 + root->right->sz;
}

Answer split(Node* root, int k) {
  unreverse(root);
  Answer ans;
  if (root == emptyNode) {
    ans.first = emptyNode;
    ans.second = emptyNode;
  } else if (k <= root->left->sz){
    ans.second = root;
    auto aux = split(root->left, k);
    ans.first = aux.first;
    ans.second->left = aux.second;
    recompute(ans.second);
  } else {
    ans.first = root;
    auto aux = split(root->right, k - root->left->sz - 1);
    ans.first->right = aux.first;
    recompute(ans.first);
    ans.second = aux.second;
  }
  return ans;
}

Node* join(Node* root1, Node* root2) {
  unreverse(root1);
  unreverse(root2);
  if (root1 == emptyNode) {
    return root2;
  } else if (root2 == emptyNode) {
    return root1;
  } else if (root1->priority > root2->priority) {
    root1->right = join(root1->right, root2);
    recompute(root1);
    return root1;
  } else {
    root2->left = join(root1, root2->left);
    recompute(root2);
    return root2;
  }
}

int acces(Node* root, int k) {
  unreverse(root);
  if (root->left->sz >= k) {
    return acces(root->left, k);
  } else if (root->left->sz + 1 == k) {
    return root->val;
  } else {
    return acces(root->right, k - root->left->sz - 1);
  }
}

Node* insert(Node* root, int k, int val) {
  Node* newNode = new Node{val, 1, ((long long)rand() << 31) ^ rand(), emptyNode, emptyNode, false};
  auto aux = split(root, k - 1);
  return join(join(aux.first, newNode), aux.second);
}

Node* erase(Node* root, int st, int dr) {
  auto p1 = split(root, st - 1);
  auto p2 = split(p1.second, dr - st + 1);
  delete p2.first;
  return join(p1.first, p2.second);
}

Node* reverse(Node* root, int st, int dr) {
  auto p1 = split(root, st - 1);
  auto p2 = split(p1.second, dr - st + 1);
  p2.first->reversed = !p2.first->reversed;
  return join(join(p1.first, p2.first), p2.second);
}

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

  srand(time(NULL));

  int N, tip;

  scanf("%d%d ", &N, &tip);

  Node* root = emptyNode;

  for (int n = 1; n <= N; ++n) {
    char c = getc(stdin);
    if (c == 'I') {
      int k, e;
      scanf("%d%d ", &k, &e);
      root = insert(root, k, e);
    } else if (c == 'A') {
      int k;
      scanf("%d ", &k);
      printf("%d\n", acces(root, k));
    } else if (c == 'R') {
      int st, dr;
      scanf("%d%d ", &st, &dr);
      root = reverse(root, st, dr);
    } else {
      int st, dr;
      scanf("%d%d ", &st, &dr);
      root = erase(root, st, dr);
    }
  }

  N = root->sz;
  for (int n = 1; n <= N; ++n)
    printf("%d ", acces(root, n));
  printf("\n");

  return 0;
}