Cod sursa(job #2674840)

Utilizator JoMeeJonas Meier JoMee Data 20 noiembrie 2020 15:22:18
Problema Secv8 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.17 kb
#include <bits/stdc++.h>

using namespace std;

ofstream fout("secv8.out");

struct TreapNode {
  int data,priority,subtreeSize;
  bool flipped;
  TreapNode* leftChild;
  TreapNode* rightChild;

  TreapNode(int p) {
    this->priority = p;
    this->subtreeSize = 0;
    this->leftChild = nullptr;
    this->rightChild = nullptr;
    this->data = 0;
  }
  TreapNode(int data, TreapNode* leftChild, TreapNode* rightChild) {
    this->data = data;
    this->flipped = false;
    this->leftChild = leftChild;
    this->rightChild = rightChild;
    this->priority = rand();
  }
};

TreapNode* nullElem = new TreapNode(RAND_MAX);

void recalc(TreapNode* node) {
  if(node == nullElem)return;
  if(node->flipped){
    node->flipped = false;
    swap(node->leftChild,node->rightChild);
    node->leftChild->flipped = !node->leftChild->flipped;
    node->rightChild->flipped = !node->rightChild->flipped;
  }
  node->subtreeSize = node->leftChild->subtreeSize + node->rightChild->subtreeSize + 1;
}

struct Treap {
  TreapNode* root;
  Treap() {
    root = nullElem;
  }

  TreapNode* join(TreapNode* t1, TreapNode* t2) {
    if(t1 == nullElem)return t2;
    if(t2 == nullElem)return t1;
    if(t1->priority < t2->priority) {
      t1->rightChild = join(t1->rightChild,t2);
      recalc(t1);
      return t1;
    } else {
      t2->leftChild = join(t1,t2->leftChild);
      recalc(t2);
      return t2;
    }
  }

  int find(int i) {
    return find(i,root)->data;
  }

  TreapNode* find(int i, TreapNode* startNode) {
    recalc(startNode);
    if(startNode->leftChild->subtreeSize == i) {
      return startNode;
    } else if(startNode->leftChild->subtreeSize > i) {
      return find(i,startNode->leftChild);
    } else {
      return find(i-startNode->leftChild->subtreeSize-1,startNode->rightChild);
    }
  }

  pair<TreapNode*, TreapNode*> split(int i, TreapNode* currRoot) {
    if(currRoot == nullElem) { return make_pair(nullElem,nullElem); };
    if(i == currRoot->leftChild->subtreeSize) {
      TreapNode* tmp = currRoot->leftChild;
      currRoot->leftChild = nullElem;
      recalc(currRoot);
      return make_pair(tmp,currRoot);
    } else if(i < currRoot->leftChild->subtreeSize) {
      auto tmp = split(i,currRoot->leftChild);
      currRoot->leftChild = tmp.second;
      recalc(currRoot);
      return make_pair(tmp.first,currRoot);
    } else {
      auto tmp = split(i-currRoot->leftChild->subtreeSize -1, currRoot->rightChild);
      currRoot->rightChild = tmp.first;
      recalc(currRoot);
      return make_pair(currRoot,tmp.second);
    }
  }

  void insertAt(int i, int val) {
    auto tmp = split(i,root);
    root = join(tmp.first,join(new TreapNode(val,nullElem,nullElem),tmp.second));
  }

  void invertRange(int l, int r) {
    auto tmp1 = split(r+1,root);
    auto tmp2 = split(l,tmp1.first);
    tmp2.second->flipped = true;
    recalc(tmp2.second);
    recalc(tmp2.second->rightChild);
    recalc(tmp2.second->leftChild);


    root = join(tmp2.first,join(tmp2.second,tmp1.second));
  }
  void deleteSubtree(TreapNode* subtree) {
    if(subtree == nullElem) { return; }
    deleteSubtree(subtree->leftChild);
    deleteSubtree(subtree->rightChild);
    delete subtree;
    subtree = nullElem;
  }

  void deleteRange(int l,int r) {
    auto tmp1 = split(r+1,root);
    auto tmp2 = split(l,tmp1.first);
    deleteSubtree(tmp2.second);
    root = join(tmp2.first,tmp1.second);
  }

  void printSubtree(TreapNode* currRoot) {
    if(currRoot == nullElem)return;
    recalc(currRoot);
    recalc(currRoot->rightChild);
    recalc(currRoot->leftChild);
    printSubtree(currRoot->leftChild);
    fout<<currRoot->data<<" ";
    printSubtree(currRoot->rightChild);
  }

  void print() {
    printSubtree(root);
    fout<<"\n";
  }

};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  Treap treap = Treap();
  ifstream fin("secv8.in");
  int n,k;
  fin>>n>>k;

  while( n --> 0) {
    char c;
    int a,b;
    fin>>c;
    if(c != 'A') {
      fin>>a>>b;
    }
    if(c == 'I') {
      treap.insertAt(a-1,b);
    }
    if(c == 'R') {
      treap.invertRange(a-1,b-1);
    }
    if(c == 'D') {
      treap.deleteRange(a-1,b-1);
    }
    if(c == 'A') {
      fin>>a;
      fout<<treap.find(a-1)<<"\n";
    }
  }
  treap.print();
}