Cod sursa(job #3253852)

Utilizator andiRTanasescu Andrei-Rares andiR Data 5 noiembrie 2024 00:06:11
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.03 kb
// Author: Tanasescu Andrei-Rares
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <deque>
#include <iomanip>
#include <vector>
#include <cassert>
#include <random>
#include <ctime>

#pragma GCC optimize("O3")

#define fi first
#define se second
#define pb push_back
#define pf push_front

using namespace std;

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

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const ll Nmax=1e6+5, inf=1e9+5;

mt19937 mt(time(0));

struct NODE{
    int x, y, sz;
    bool rev;
    NODE* left, *right;

    NODE(int val){
        x=val;
        y=mt();
        sz=1;
        rev=0;
        left=right=nullptr;
    }
};

// marimea subarborelui
inline int get_sz(NODE* node){
    if (node==nullptr)
        return 0;
    return node->sz;
}
// indicele pe care il are in subarbore
inline int get_ind(NODE* node){
    assert(node!=nullptr);
    return get_sz(node->left)+1;
}
// recalculam parametrii nodului
inline void upd_node(NODE* node){
    assert(node!=nullptr);
    node->sz=get_sz(node->left)+1+get_sz(node->right);
}

inline void push_lazy(NODE* node){
    assert(node!=nullptr);
    if (node->rev){
        node->rev=0;
        if (node->left!=nullptr)
            node->left->rev^=1;
        if (node->right!=nullptr)
            node->right->rev^=1;

        swap(node->left, node->right);
    }
}

// split pana la pos
pair<NODE*, NODE*> split(NODE* treap, int pos){
    if (treap==nullptr)
        return {nullptr, nullptr};
    
    push_lazy(treap);

    int ind=get_ind(treap);
    if (ind<=pos){
        auto rs=split(treap->right, pos-ind);
        treap->right=rs.fi;
        upd_node(treap);
        return {treap, rs.se};
    }
    else{
        auto ls=split(treap->left, pos);
        treap->left=ls.se;
        upd_node(treap);
        return {ls.fi, treap};
    }
}
// merge, y-ul mai mare e dominant
NODE* merge(NODE* ltreap, NODE* rtreap){
    if (ltreap==nullptr && rtreap==nullptr)
        return nullptr;
    if (ltreap==nullptr)
        return rtreap;
    if (rtreap==nullptr)
        return ltreap;

    push_lazy(ltreap);
    push_lazy(rtreap);
    
    if (ltreap->y>rtreap->y){
        ltreap->right=merge(ltreap->right, rtreap);
        upd_node(ltreap);
        return ltreap;
    }
    else{
        rtreap->left=merge(ltreap, rtreap->left);
        upd_node(rtreap);
        return rtreap;
    }
}

inline NODE* insert(NODE* treap, int pos, int val){
    auto p1_2=split(treap, pos-1);
    NODE* new_treap= new NODE(val);
    return merge(p1_2.fi, merge(new_treap, p1_2.se));
}
inline NODE* erase(NODE* treap, int l, int r){
    auto p1_23=split(treap, l-1);
    auto p2_3=split(p1_23.se, r-l+1 
    );
    return merge(p1_23.fi, p2_3.se);
}
inline NODE* reverse(NODE* treap, int l, int r){
    auto p1_23=split(treap, l-1);
    auto p2_3=split(p1_23.se, r-l+1);

    p2_3.fi->rev^=1;

    return merge(p1_23.fi, merge(p2_3.fi, p2_3.se));
}
int acces(NODE* treap, int pos){
    assert(treap!=nullptr);
    push_lazy(treap);

    int ind=get_ind(treap);
    if (ind==pos)
        return treap->x;
    if (ind<pos)
        return acces(treap->right, pos-ind);
    else return acces(treap->left, pos);
}
void afis(NODE* treap){
    if (treap==nullptr)
        return;

    push_lazy(treap);

    afis(treap->left);
    fout<<treap->x<<' ';
    afis(treap->right);
}

NODE* treap=nullptr;

int n;
bool Erev;

int main()
{
    fin>>n>>Erev;
    char t; int a, b;
    for (int i=0; i<n; i++){
        fin>>t;
        if (t=='I'){
            fin>>a>>b;
            treap=insert(treap, a, b);
        }
        else if (t=='A'){
            fin>>a;
            fout<<acces(treap, a)<<'\n';       
        }
        else if (t=='R'){
            fin>>a>>b;
            treap=reverse(treap, a, b);
        }
        else{
            fin>>a>>b;
            treap=erase(treap, a, b);
        }
        /*afis(treap);
        fout<<'\n';*/
    }
    afis(treap);

    return 0;
}