Cod sursa(job #2734670)

Utilizator Asgari_ArminArmin Asgari Asgari_Armin Data 1 aprilie 2021 11:15:22
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.21 kb
#include <bits/stdc++.h>
#define debug(x) cerr << #x << " " << x << "\n"

using namespace std;

ifstream fin( "secv8.in" );
ofstream fout( "secv8.out" );

const int MOD = 1e9;

struct Node{
  Node* left;
  Node* right;
  int val, sz, prio;
  bool rev;
};
Node* EmptyNode = new Node{NULL, NULL, 0, 0, 0, 0};
Node* root = EmptyNode;

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

void unrev( Node* root ) {
  if( root != EmptyNode && root->rev == 1 ){
    swap(root->left, root->right);
    root->rev = 0;
    root->left->rev ^= 1;
    root->right->rev ^= 1;
  }
}

Node* join( Node *stanga, Node* dreapta ){
  unrev(stanga);
  unrev(dreapta);
  if( stanga == EmptyNode )
    return dreapta;
  if( dreapta == EmptyNode )
    return stanga;
  if( stanga->prio > dreapta->prio ){
    stanga->right = join(stanga->right, dreapta);
    recompute(stanga);
    return stanga;
  }
  else {
    dreapta->left = join(stanga, dreapta->left);
    recompute(dreapta);
    return dreapta;
  }
}

pair<Node*, Node*> split( Node* root, int pos ){
  if( root == EmptyNode )
    return {EmptyNode, EmptyNode};
  unrev(root);
  pair <Node*, Node*> ans;
  if( root->left->sz >= pos ){
    ans.second = root;
    pair<Node*, Node*> aux = split(root->left, pos);
    ans.first = aux.first;
    ans.second->left = aux.second;
    recompute(ans.second);
  }
  else {
    ans.first = root;
    pair<Node*, Node*> aux = split(root->right, pos - root->left->sz - 1);
    ans.first->right = aux.first;
    ans.second = aux.second;
    recompute(ans.first);
  }
  return ans;
}

Node* Delete( Node *root, int from, int to ){
  pair<Node*, Node*> stanga = split(root, from - 1);
  pair<Node*, Node*> dreapta = split(stanga.second, to - from + 1);
  return join(stanga.first, dreapta.second);
}

Node* Insert( Node* root, int pos, int val ){
  pair<Node*, Node*> aux = split(root, pos - 1);
  Node* NewElement = new Node{EmptyNode, EmptyNode, val, 1, rand() % MOD, 0};
  return join(join(aux.first, NewElement), aux.second);
}

Node* Reverse( Node* root, int from, int to ){
  pair<Node*, Node*> stanga = split(root, from - 1);
  pair<Node*, Node*> dreapta = split(stanga.second, to - from + 1);
  dreapta.first->rev ^= 1;
  return join(join(stanga.first, dreapta.first), dreapta.second);
}

int access( Node* root, int pos ){
  unrev(root);
  if( 1 + root->left->sz == pos )
    return root->val;
  if( root->left->sz >= pos )
    return access(root->left, pos);
  else
    return access(root->right, pos - root->left->sz - 1);
}

int main() {
  srand(time(NULL));
  int q, ok, from, to, pos, val, i;
  char ch;
  fin >> q >> ok;
  while( q-- ){
    fin >> ch;

    if( ch == 'A' ){
      fin >> pos;
      fout << access(root, pos) << "\n";
    }
    else if( ch == 'I' ){
      fin >> pos >> val;
      root = Insert(root, pos, val);
    }
    else if( ch == 'R' ){
      fin >> from >> to;
      root = Reverse(root, from, to);
    }
    else if( ch == 'D' ){
      fin >> from >> to;
      root = Delete(root, from, to);
    }
  }
  for( i = 1; i <= root->sz; ++i )
    fout << access(root, i) << " ";
  return 0;
}