Cod sursa(job #1936933)

Utilizator MoodyFaresFares Mohamad MoodyFares Data 23 martie 2017 16:02:25
Problema Secv8 Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.31 kb
#include <cstdio>
#include <algorithm>

struct Node {
  bool reversed;
  int val;
  int size;
  Node* left;
  Node* right;
};

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

void unreverse(Node* root) {
  if (root != emptyNode && root->reversed) {
    std::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->size = root->left->size + 1 + root->right->size;
}

std::pair<Node*, Node*> split(Node* root, int k) {
  unreverse(root);
  std::pair<Node*, Node*> answer;
  if (root == emptyNode) {
    answer.first = emptyNode;
    answer.second = emptyNode;
  } else if (k <= root->left->size) {
    answer.second = root;
    auto p = split(root->left, k);
    answer.first = p.first;
    answer.second->left = p.second;
    recompute(answer.second);
  } else {
    answer.first = root;
    auto p = split(root->right, k - root->left->size - 1);
    answer.first->right = p.first;
    recompute(answer.first);
    answer.second = p.second;
  }
  return answer;
}

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

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

Node* insert(Node* root, int k, Node* val) {
  auto p = split(root, k - 1);
  return join(join(p.first, val), p.second);
}

Node* insert(Node* root, int k, int val) {
  return insert(root, k, new Node{false, val, 1, emptyNode, emptyNode});
}

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

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

Node* reverse(Node* root, int i, int j) {
  auto p1 = split(root, i - 1);
  auto p2 = split(p1.second, j - i + 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);
  
  int N;
  int existaReverse;
  Node *root = emptyNode;
  scanf("%d%d", &N, &existaReverse);
  char ch;
  getc(stdin);
  int k, val, i, j;
  for (int i = 1; i <= N; ++i) {
    ch = getc(stdin);
    switch (ch) {
      case 'I':
        scanf("%d%d", &k, &val);
        root = insert(root, k, val);
        break;
      case 'A':
        scanf("%d", &k);
        printf("%d\n", access(root, k));
        break;
      case 'R':
        scanf("%d%d", &i, &j);
        root = reverse(root, i, j);
        break;
      case 'D':
        scanf("%d%d", &i, &j);
        root = erase(root, i, j);
        break;
    }
    getc(stdin);
  }
  for (i = 1; i <= root->size; ++i)
    printf("%d ", access(root, i));
  printf("\n");
  return 0;
}