Cod sursa(job #1693863)

Utilizator mihail.jianuJianu Mihail mihail.jianu Data 24 aprilie 2016 00:25:15
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.86 kb
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<algorithm>
using namespace std;
class Hash{
    public:
        int r1,r2;
};
class Treap{
    public:
        int size;
        int val;
        int key;
        bool rev;
        Treap* left;
        Treap* right;
};
int my_rand(){
    return rand()*rand()+rand();
}
Treap* same(Treap* node){
    Treap* res=new Treap;
    if(!node)
        return NULL;
    res->size=node->size;
    res->val=node->val;
    res->key=node->key;
    res->rev=node->rev;
    res->left=node->left;
    res->right=node->right;
    return res;
}
Treap* propag(Treap* node){
    Treap* res=new Treap;
    res=same(node);
    if(node)
        if(node->rev==true){
            res->rev=false;
            res->left=same(node->right);
            res->right=same(node->left);
            if(res->right)
                res->right->rev^=1;
            if(res->left)
                res->left->rev^=1;
        }
    return res;
}
int get_size(Treap* node){
    if(!node)
        return 0;
    return node->size;
}
void set_size(Treap* node){
    if(!node)
        return;
    node->size=get_size(node->left)+1+get_size(node->right);
}
pair<Treap*,Treap*>split(Treap* node,int size1){
    pair<Treap*,Treap*>res;
    res.first=new Treap;
    res.second=new Treap;
    node=propag(node);
    if(!node){
        res.first=NULL;
        res.second=NULL;
        return res;
    }
    if(get_size(node->left)+1<=size1){
        res.first=same(node);
        pair<Treap*,Treap*> split_t=split(node->right,size1-get_size(node->left)-1);
        res.first->right=split_t.first;
        res.second=split_t.second;
    }
    else{
        res.second=same(node);
        pair<Treap*,Treap*> split_t=split(node->left,size1);
        res.second->left=split_t.second;
        res.first=split_t.first;
    }
    set_size(res.first);
    set_size(res.second);
    delete node;
    return res;
}
Treap* join(Treap* node1,Treap* node2){
    Treap* res=new Treap;
    node1=propag(node1);
    node2=propag(node2);
    if(node1==NULL)
        return node2;
    if(node2==NULL)
        return node1;
    if(node1->key>node2->key){
        res=same(node1);
        res->right=join(node1->right,node2);
    }
    else{
        res=same(node2);
        res->left=join(node1,node2->left);
    }
    set_size(res);
    delete node1;
    delete node2;
    return res;
}
Treap* insert(Treap* node,int val,int pos,int key=my_rand()){
    node=propag(node);
    Treap* res=new Treap();
    if(node==NULL||key>node->key){
        pair<Treap*,Treap*>split_t=split(node,pos);
        res->val=val;
        res->size=get_size(node)+1;
        res->key=key;
        res->rev=false;
        res->left=split_t.first;
        res->right=split_t.second;
        return res;
    }
    else if(get_size(node->left)>=pos){
        res=same(node);
        res->left=insert(res->left,val,pos,key);
    }
    else{
        res=same(node);
        res->right=insert(res->right,val,pos-get_size(node->left)-1,key);
    }
    set_size(res);
    delete node;
    return res;
}
Treap* erase(Treap* node,int l,int r){
    node=propag(node);
    pair<Treap*,Treap*>split_t1=split(node,l-1);
    pair<Treap*,Treap*>split_t2=split(split_t1.second,r-l+1);
    Treap* res=join(split_t1.first,split_t2.second);
    delete node;
    return res;
}
Treap* reverse(Treap* node,int l,int r){
    Treap* res=new Treap;
    node=propag(node);
    pair<Treap*,Treap*>split_t1=split(node,l-1);
    pair<Treap*,Treap*>split_t2=split(split_t1.second,r-l+1);
    split_t2.first->rev^=1;
    res=join(split_t2.first,split_t2.second);
    res=join(split_t1.first,res);
    delete node;
    return res;
}
int query(Treap* node,int pos){
    node=propag(node);
    pair<Treap*,Treap*>split_t1=split(node,pos);
    pair<Treap*,Treap*>split_t2=split(split_t1.second,1);
    return split_t2.first->val;
}
void print(Treap* node){
    if(!node)
        return;
    print(node->left);
    printf("%d ",node->val);
    print(node->right);
}
Treap* my_treap=NULL;
int main(){
    freopen("treap.in","r",stdin);
    freopen("treap.out","w",stdout);
    int nrq,t;
    scanf("%d%d\n",&nrq,&t);
    while(nrq--){
        char c;
        scanf("%c",&c);
        if(c=='I'){
            int pos,val;
            scanf("%d%d\n",&pos,&val);
            my_treap=insert(my_treap,val,pos-1);
        }
        else if(c=='A'){
            int pos;
            scanf("%d\n",&pos);
            printf("%d\n",query(my_treap,pos-1));
        }
        else if(c=='R'){
            int l,r;
            scanf("%d%d\n",&l,&r);
            my_treap=reverse(my_treap,l,r);
        }
        else{
            int l,r;
            scanf("%d%d\n",&l,&r);
            my_treap=erase(my_treap,l,r);
        }
    }
    print(my_treap);
    return 0;
}