Cod sursa(job #1174893)

Utilizator CosminRusuCosmin Rusu CosminRusu Data 24 aprilie 2014 09:06:15
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.98 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <bitset>
#include <string.h>
#include <algorithm>
#include <iomanip>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <deque>

using namespace std;

const char infile[] = "secv8.in";
const char outfile[] = "secv8.out";

ifstream fin(infile);
ofstream fout(outfile);

const int MAXN = 100005;
const int oo = (1 << 30) + 1;

typedef vector<int> Graph[MAXN];
typedef vector<int> :: iterator It;

const inline int min(const int &a, const int &b) { if( a > b ) return b;   return a; }
const inline int max(const int &a, const int &b) { if( a < b ) return b;   return a; }
const inline void Get_min(int &a, const int b)    { if( a > b ) a = b; }
const inline void Get_max(int &a, const int b)    { if( a < b ) a = b; }

int N;
bool rev;

struct Treap {
    Treap *left, *right;
    int key, priority, subTree;
    bool rev;
    Treap(Treap *_left, Treap *_right, int _key, int _priority) {
        left = _left;
        right = _right;
        ///value = _value;
        key = _key;
        priority = _priority;
    }
} *Root, *NIL;

inline void updateSubTree(Treap *&Node) {
    Node->subTree = 1 + Node->left->subTree + Node->right->subTree;
}

inline void lazyReverse(Treap *&Node) {
    if(Node->rev) {
        swap(Node->left, Node->right);
        Node->rev = 0;
        Node->left->rev ^= 1;
        Node->right->rev ^= 1;
    }
}

inline void rotateLeft(Treap *&Node) {
    lazyReverse(Node);
    lazyReverse(Node->left);
    lazyReverse(Node->right);

    Treap *aux = Node->left;
    Node->left = aux->right;
    aux->right = Node;
    Node = aux;

    updateSubTree(Node->left);
    updateSubTree(Node->right);
    updateSubTree(Node);
}

inline void rotateRight(Treap *&Node) {
    lazyReverse(Node);
    lazyReverse(Node->left);
    lazyReverse(Node->right);

    Treap *aux = Node->right;
    Node->right = aux->left;
    aux->left = Node;
    Node = aux;

    updateSubTree(Node->left);
    updateSubTree(Node->right);
    updateSubTree(Node);
}

inline void Balance(Treap *& Node) {
    lazyReverse(Node);
    if(Node->left->priority > Node->priority)
        rotateLeft(Node);
    if(Node->right->priority > Node->priority)
        rotateRight(Node);
    updateSubTree(Node);
}

void Insert(Treap *& Node, int pos, int key, int priority) {
    if(Node == NIL) {
        Node = new Treap(NIL, NIL, key, priority);
        return;
    }
    lazyReverse(Node);
    if(Node->left->subTree + 1 >= pos)
        Insert(Node->left, pos, key, priority);
    else Insert(Node->right, pos - Node->left->subTree - 1, key, priority);
    updateSubTree(Node);
    Balance(Node);
    updateSubTree(Node);
}

void Erase(Treap *&Node, int pos) {
    lazyReverse(Node);
    if(Node->left->subTree + 1 == pos) {
        if(Node->left == NIL && Node->right == NIL) {
            delete Node;
            Node = NIL;
            return;
        }
        if(Node->left->priority > Node->priority) {
            rotateLeft(Node);
            Erase(Node->right, pos);
        }
        else {
            rotateRight(Node);
            Erase(Node->left, pos);
        }
    }
    else {
        if(Node->left->subTree + 1 > pos)
            Erase(Node->left, pos);
        else Erase(Node->right, pos - Node->left->subTree - 1);
    }
    updateSubTree(Node);
}

inline bool Access(Treap *&Node, int k) { /// guarantee it exist
    if(Node->left->subTree + 1 == k)
        return Node->left->key;
    if(Node->left->subTree + 1 < k)
        return Access(Node->left, k);
        else return Access(Node->right, k - Node->left->subTree - 1);
}

inline void Split(Treap *Node, Treap *T1, Treap *T2, int x) {
    Insert(Node, 0, x, oo);
    T1 = Node->left;
    T2 = Node->right;
    delete Node;
    Node = NIL;
}

inline void Join(Treap *Node, Treap *T1, Treap *T2) {
    Node = new Treap(T1, T2, 0, oo);
    updateSubTree(Node);
    Erase(Node, Node->left->subTree + 1);
}

inline bool Rotate(Treap *&Node, int x, int y) {
    Treap *A, *B, *C, *D;
    Split(Node, A, B, y + 1);
    Split(A, C, D, x);
    D->rev = true;
    Join(A, C, D);
    Join(Node, A, B);
}

inline void EraseSequence(Treap *&Node, int x, int y) {
    Treap *A, *B, *C, *D;
    Split(Node, A, B, y + 1);
    Split(A, C, D, x);
    Join(Node, C, B);
}

int main() {
    NIL = new Treap(0, 0, 0, 0);
    Root = NIL;
    srand(time(NULL));
    for(fin >> N >> rev ; N -- ; ) {
        char op; int x, y;
        fin >> op;
        switch(op) {
            case 'I':
                fin >> x >> y;
                Insert(Root, x, y, rand() % oo + 1);
                break;
            case 'A':
                fin >> x;
                fout << Access(Root, x) << '\n';
                break;
            case 'R':
                fin >> x >> y;
                Rotate(Root, x, y);
                break;
            case 'D':
                fin >> x >> y;
                EraseSequence(Root, x, y);
                break;
        }
    }
    fin.close();
    fout.close();
    return 0;
}