Cod sursa(job #2674915)

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

using namespace std;

struct TreapNode {
  int data, priority, weight;
  bool inverted;
  TreapNode *lc, *rc;
  TreapNode(int p) :  data(0), priority(p), weight(0), inverted(false), lc(nullptr), rc(nullptr) {
  }
  TreapNode(int data, TreapNode* l, TreapNode* r) : data(data), priority(rand()), weight(1), lc(l), rc(r), inverted(false) {
  }

} *nil = new TreapNode(RAND_MAX);

void recalc(TreapNode* node) {
  if(node == nil)return;
  if(node->inverted) {
    node->inverted = false;
    swap(node->rc,node->lc);
    node->rc->inverted ^= 1;
    node->lc->inverted ^= 1;
  }
  node->weight = 1 + node->lc->weight + node->rc->weight;
}

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

  TreapNode* join(TreapNode* t1, TreapNode* t2) {
    if(t1 == nil) return t2;
    if(t2 == nil) return t1;
    recalc(t1);
    recalc(t2);
    if(t1->priority < t2->priority) {
      t1->rc = join(t1->rc, t2);
      recalc(t1);
      return t1;
    } else {
      t2->lc = join(t1,t2->lc);
      recalc(t2);
      return t2;
    }
  }

  pair<TreapNode*, TreapNode*> split(int pos, TreapNode* currRoot) {
    if(currRoot == nil) return make_pair(nil,nil);
    if(pos == currRoot->lc->weight) {
      TreapNode* tmp = currRoot->lc;
      currRoot->lc = nil;
      recalc(currRoot);
      return make_pair(tmp,currRoot);
    } else if(pos < currRoot->lc->weight) {
      auto tmp = split(pos, currRoot->lc);
      currRoot->lc = tmp.second;
      recalc(currRoot);
      return make_pair(tmp.first,currRoot);
    } else {
      auto tmp = split(pos - currRoot->lc->weight - 1, currRoot->rc);
      currRoot->rc = tmp.first;
      recalc(currRoot);
      return make_pair(currRoot, tmp.second);
    }
  }

  tuple <TreapNode*, TreapNode*, TreapNode*> split_3t (int l, int r, TreapNode* currRoot) {
    auto tmp1 = split(r, currRoot);
    auto tmp2 = split(l, tmp1.first);
    return make_tuple(tmp2.first, tmp2.second, tmp1.second);
  }
  TreapNode* join_3t (TreapNode* t1, TreapNode* t2, TreapNode* t3) {
    return join(t1, join(t2,t3));
  }

  TreapNode* find(int pos, TreapNode* currRoot) {
    if(pos == currRoot->lc->weight) {
      return currRoot;
    } else if(pos < currRoot->lc->weight) {
      return find(pos, currRoot->lc);
    } else {
      return find(pos - currRoot->lc->weight-1, currRoot->rc);
    }
  }

  int find(int pos) {
    return find(pos, root)->data;
  }
  void deleteTreapNode(TreapNode* node) {
    if(node == nil) return;
    deleteTreapNode(node->rc);
    deleteTreapNode(node->lc);
    delete node;
    node = nil;
  }
  void insertAt(int pos, int val) {
    auto tmp = split(pos, root);
    root = join_3t(tmp.first, new TreapNode(val, nil, nil), tmp.second);
  }

  void deleteRange(int l, int r) {
    auto t = split_3t(l,r,root);
    deleteTreapNode(get<1>(t));
    root = join(get<0>(t),get<2>(t));
  }
  void invertRange(int l, int r) {
    auto t = split_3t(l,r,root);
    get<1>(t)->inverted ^= 1;
    recalc(get<1>(t));
    root = join_3t(get<0>(t), get<1>(t), get<2>(t));
  }

  void printSubtree(TreapNode* currRoot) {
    if(currRoot == nil) return;
    printSubtree(currRoot->lc);
    cout<<currRoot->data<<" ";
    printSubtree(currRoot->rc);
  }

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

};

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  freopen("secv8.in","r", stdin);
  freopen("secv8.out","w", stdout);

  Treap t = Treap();

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