Cod sursa(job #1609700)

Utilizator IonSebastianIon Sebastian IonSebastian Data 22 februarie 2016 22:43:58
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 6.06 kb
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <algorithm>

using std::pair;

class Treap;
void updateSize(Treap* node);
int myRandom();

class Treap {
public:
  int value;
  int priority; // Max-Heap
  int size;
  bool reversed;
  Treap* left;
  Treap* right;

  Treap(int value, int priority = myRandom(), int size = 0,
        bool reversed = false, Treap* left = NULL, Treap* right = NULL) {
    this->value = value;
    this->priority = priority;
    this->size = size;
    this->reversed = reversed;
    this->left = left;
    this->right = right;
    updateSize(this);
  }
};

Treap* duplicate(const Treap* node) {
  Treap* answer = new Treap(0);
  answer->value = node->value;
  answer->priority = node->priority;
  answer->size = node->size;
  answer->reversed = node->reversed;
  answer->left = node->left;
  answer->right = node->right;
  return answer;
}

Treap* propagate(Treap* node) {
  Treap* newNode;
  if (node != NULL && node->reversed) {
    newNode = duplicate(node);
    newNode->reversed = false;
    if (node->left != NULL) {
      newNode->right = duplicate(node->left);
      newNode->right->reversed ^= 1;
    } else {
      newNode->right = NULL;
    }
    if (node->right != NULL) {
      newNode->left = duplicate(node->right);
      newNode->left->reversed ^= 1;
    } else {
      newNode->left = NULL;
    }
  } else {
    newNode = node;
  }
  return newNode;
}

int getSize(Treap* node) {
  if (node == NULL) {
    return 0;
  } else {
    return node->size;
  }
}

void updateSize(Treap* node) {
  if (node != NULL)
    node->size =
        getSize(node->left) + 1 + getSize(node->right);
}

Treap* find(Treap* node, int index) {
  node = propagate(node);
  if (node == NULL || node->size <= index) {
    return NULL;
  }
  if (index < getSize(node->left)) {
    return find(node->left, index);
  } else if (index == getSize(node->left)) {
    return node;
  } else { // if (leftSize < index)
    return find(node->right, index - getSize(node->left) - 1);
  }
}

pair<Treap*, Treap*> split(Treap* node, int size1) {
  node = propagate(node);
  pair<Treap*, Treap*> answer;
  if (node == NULL) {
    answer.first = NULL;
    answer.second = NULL;
  } else {

    if (getSize(node->left) + 1 <= size1) {
      answer.first = new Treap(node->value, node->priority, 0,false,node->left, NULL);
      answer.first->value = node->value;
      answer.first->priority = node->priority;
      answer.first->reversed = false;
      answer.first->left = node->left;
      pair<Treap*, Treap*> splitAnswer =
          split(node->right, size1 - (getSize(node->left) + 1));
      answer.first->right = splitAnswer.first;
      answer.second = splitAnswer.second;
    } else { // size1 < leftSize + 1
      answer.second = new Treap(node->value,node->priority, 0,false, NULL,node->right);
      answer.second->value = node->value;
      answer.second->priority = node->priority;
      answer.second->reversed = false;
      answer.second->right = node->right;
      pair<Treap*, Treap*> splitAnswer =
          split(node->left, size1);
      answer.first = splitAnswer.first;
      answer.second->left = splitAnswer.second;
    }
    updateSize(answer.first);
    updateSize(answer.second);
  }
  return answer;
}

Treap* join(Treap* first, Treap* second) {
  first = propagate(first);
  second = propagate(second);
  if (first == NULL) {
    return second;
  } else if (second == NULL) {
    return first;
  } else if (second->priority < first->priority) {
    Treap* newNode = duplicate(first);
    newNode->right = join(first->right, second);
    updateSize(newNode);
    return newNode;
  } else { // if (first->priority < second->priority)
    Treap* newNode = duplicate(second);
    newNode->left = join(first, second->left);
    updateSize(newNode);
    return newNode;
  }
}

int myRandom() {
  return (rand() << 19) ^ rand();
}

FILE *in, *out;

//void dump(FILE* dumpFile, Treap* node, int depth = 0) {
//  propagate(node);
//  if (node != NULL) {
//    dump(dumpFile, node->right, depth + 1);
//    fprintf(dumpFile, "%12d  %2d ", node->priority, node->size);
//    for (int i = 0; i < depth; i++) {
//      fprintf(dumpFile, "  ");
//    }
//    fprintf(dumpFile, "%d\n", node->value);
//    dump(dumpFile, node->left, depth + 1);
//  }
//}

void print(Treap* node) {
    if(node != NULL) {
        propagate(node);
        print(node->left);
        fprintf(out, "%d ", node->value);
        print(node->right);
    }
}

int main(void) {

//  FILE* dumpFile = fopen("dumpFile.txt", "w");

  srand(time(NULL));

  in = fopen("secv8.in", "r");
  out = fopen("secv8.out", "w");

  int n, inutil;
  char c;

  fscanf(in, "%d%d", &n, &inutil);

  int cn = n;
  int poz, x;
  int i, j;

  Treap *t = NULL;

  while(cn > 0) {
        do {
            fscanf(in, "%c", &c);
        }while(c < 'A' || c > 'Z');

        if(c == 'I') {
            fscanf(in, "%d%d", &poz, &x);

            Treap* newNode = new Treap(x);

            pair<Treap*, Treap*> splitAnswer = split(t, poz-1);

            t = join(join(splitAnswer.first, newNode), splitAnswer.second);

        } else if(c == 'A'){
            fscanf(in, "%d", &poz);

            Treap* answer = find(t, poz-1);

            if(answer != NULL)
              fprintf(out, "%d\n", answer->value);

        } else if(c == 'R') {
            fscanf(in, "%d%d", &i, &j);

            pair<Treap*, Treap*> split1 = split(t, i-1);
            pair<Treap*, Treap*> split2 = split(split1.second, j-i+1);

            split2.first->reversed ^= 1;

            t = join(join(split1.first, split2.first), split2.second);

        } else {
            fscanf(in, "%d%d", &i, &j);

            pair<Treap*, Treap*> split1 = split(t, i-1);
            pair<Treap*, Treap*> split2 = split(split1.second, j-i+1);

            t = join(split1.first, split2.second);
        }
        cn--;
  }

  print(t);

  fclose(in);
  fclose(out);
//  fclose(dumpFile);
  return 0;
}