Cod sursa(job #3296717)

Utilizator Tudor06MusatTudor Tudor06 Data 15 mai 2025 20:23:32
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 6.1 kb
#include <bits/stdc++.h>

using namespace std;
class InParser{private:FILE *fin;char *buff;int sp;char read_ch() {++sp;if (sp == 4096) {sp = 0;fread(buff, 1, 4096, fin);}return buff[sp];}public:InParser(const char* nume) {fin = fopen(nume, "r");buff = new char[4096]();sp = 4095;}InParser& operator >> (int &n) {char c;while (!isdigit(c = read_ch()) && c != '-');int sgn = 1;if (c == '-') {n = 0;sgn = -1;} else {n = c - '0';}while (isdigit(c = read_ch())) {n = 10 * n + c - '0';}n *= sgn;return *this;}InParser& operator >> (long long &n) {char c;n = 0;while (!isdigit(c = read_ch()) && c != '-');long long sgn = 1;if (c == '-') {n = 0;sgn = -1;} else {n = c - '0';}while (isdigit(c = read_ch())) {n = 10 * n + c - '0';}n *= sgn;return *this;}InParser& operator >> (char &n){while(n = read_ch() , (n < 'A' || 'Z' < n));return *this;}};
class OutParser {private:FILE *fout;char *buff;int sp;void write_ch(char ch) {if (sp == 50000) {fwrite(buff, 1, 50000, fout);sp = 0;buff[sp++] = ch;} else {buff[sp++] = ch;}}public:OutParser(const char* name) {fout = fopen(name, "w");buff = new char[50000]();sp = 0;}~OutParser() {fwrite(buff, 1, sp, fout);fclose(fout);}OutParser& operator << (int vu32) {if (vu32 <= 9) {write_ch(vu32 + '0');} else {(*this) << (vu32 / 10);write_ch(vu32 % 10 + '0');}return *this;}OutParser& operator << (long long vu64) {if (vu64 <= 9) {write_ch(vu64 + '0');} else {(*this) << (vu64 / 10);write_ch(vu64 % 10 + '0');}return *this;}OutParser& operator << (char ch) {write_ch(ch);return *this;}OutParser& operator << (const char *ch) {while (*ch) {write_ch(*ch);++ch;}return *this;}};

InParser fin( "secv8.in" );
OutParser fout( "secv8.out" );

mt19937 rng( time( 0 ) );

struct Treap {
    struct Node {
        int l = 0;
        int r = 0;
        int siz = 0;
        int priority = 0;
        int key = 0;
        bool flip = false;
    };

    vector <Node> T;

    Treap() : T(1) {
        T[0].priority = rng();
    }

    void propag( int node ) {
        if ( node && T[node].flip ) {
            swap( T[node].l, T[node].r );
            if ( T[node].l ) T[T[node].l].flip ^= 1;
            if ( T[node].r ) T[T[node].r].flip ^= 1;
            T[node].flip = false;
        }
    }
    void calcSize( int node ) {
        if ( node != 0 ) {
            T[node].siz = T[T[node].l].siz + 1 + T[T[node].r].siz;
        }
    }
    int searchByKey( int node, int key ) {
        propag( node );
        if ( node == 0 || T[node].key == key ) return T[node].key;
        if ( key < T[node].key ) {
            return searchByKey( T[node].l, key );
        }
        return searchByKey( T[node].r, key );
    }
    int NthElement( int node, int n ) {
        propag( node );
        if ( node == 0 || T[T[node].l].siz + 1 == n ) return T[node].key;

        if ( T[T[node].l].siz >= n ) {
            return NthElement( T[node].l, n );
        }
        return NthElement( T[node].r, n - T[T[node].l].siz - 1 );
    }
    int joinTreaps( int node1, int node2 ) {
        propag( node1 );
        propag( node2 );

        if ( node1 == 0 || node2 == 0 ) return max( node1, node2 );
        if ( T[node1].priority > T[node2].priority ) {
            T[node1].r = joinTreaps( T[node1].r, node2 );
            calcSize( node1 );
            return node1;
        }
        T[node2].l = joinTreaps( node1, T[node2].l );
        calcSize( node2 );
        return node2;
    }
    int flipNode( int node ) {
        if ( node ) {
            T[node].flip ^= 1;
        }
        return node;
    }
    pair <int, int> splitBySize( int node, int n ) {
        propag( node );
        if ( node == 0 ) return {0, 0};
        if ( n == 0 ) return {0, node};
        if ( n == T[node].siz ) return {node, 0};

        if ( T[T[node].l].siz >= n ) {
            auto splitedTreap = splitBySize( T[node].l, n );
            T[node].l = splitedTreap.second;
            calcSize( node );
            return { splitedTreap.first, node };
        }
        auto splitedTreap = splitBySize( T[node].r, n - T[T[node].l].siz - 1 );
        T[node].r = splitedTreap.first;
        calcSize( node );
        return { node, splitedTreap.second };
    }
    int createTreap( int val ) {
        T.push_back( Node{ 0, 0, 1, (int)rng(), val, false } );
        return T.size() - 1;
    }
    void getKeys( int node, vector <int>& keys ) {
        propag( node );
        if ( node == 0 ) return;
        getKeys( T[node].l, keys );
        keys.push_back( T[node].key );
        getKeys( T[node].r, keys );
    }
    void printTreap( int root ) {
        vector <int> v;
        getKeys( root, v );
        for ( auto x : v ) fout << x << ' ';
        fout << '\n';
    }
};

int main() {

    int q, root = 0, reversable;
    fin >> q >> reversable;
    Treap treap;
    for ( int t = 0; t < q; t ++ ) {
        char op;
        fin >> op;
            
        if ( op == 'I' ) {
            int val, poz;
            fin >> poz >> val;

            auto splitedTreaps = treap.splitBySize( root, poz - 1 );

            int newNode = treap.createTreap( val );

            root = treap.joinTreaps( treap.joinTreaps( splitedTreaps.first, newNode ), splitedTreaps.second );
        } else if ( op == 'A' ) {
            int poz;
            fin >> poz;
            fout << treap.NthElement( root, poz ) << '\n';
        } else if ( op == 'R' ) {
            int i, j;
            fin >> i >> j;
            auto splitedTreaps = treap.splitBySize( root, j );
            auto splitedTreaps2 = treap.splitBySize( splitedTreaps.first, i - 1 );

            treap.flipNode( splitedTreaps2.second );

            root = treap.joinTreaps( treap.joinTreaps( splitedTreaps2.first, splitedTreaps2.second ), splitedTreaps.second );
        } else {
            int i, j;
            fin >> i >> j;
            auto splitedTreaps = treap.splitBySize( root, j );
            auto splitedTreaps2 = treap.splitBySize( splitedTreaps.first, i - 1 );
            
            root = treap.joinTreaps( splitedTreaps2.first, splitedTreaps.second );
        }
    }
    treap.printTreap( root );
    return 0;
}