Cod sursa(job #1525736)

Utilizator fanache99Constantin-Buliga Stefan fanache99 Data 15 noiembrie 2015 15:03:33
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.48 kb
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct treap{
    int priority;
    int size;
    int value;
    bool reversed;
    treap *left;
    treap *right;
    treap(){
        reversed=false;
        priority=value=size=0;
        left=right=NULL;
    }
};
treap* root;
treap* nil;
int get_size(treap* node){
    if(node==NULL)
        return 0;
    return node->size;
}
void update(treap *&node){
    if(node!=NULL)
        node->size=1+get_size(node->left)+get_size(node->right);
}
void reverse_node(treap *&node){
    if(node==NULL)
        return;
    node->reversed^=1;
}
void propagate(treap *&node){
    treap* answer;
    if(node==NULL||node->reversed==false)
        return;
    node->reversed=false;
    swap(node->left,node->right);
    reverse_node(node->left);
    reverse_node(node->right);
}
pair<treap*,treap*> split(treap* node,int size){
    pair<treap*,treap*> answer;
    propagate(node);
    if(node==NULL){
        answer.first=answer.second=NULL;
        return answer;
    }
    if(get_size(node->left)<size){
        pair<treap*,treap*> split_answer=split(node->right,size-get_size(node->left)-1);
        answer.first=new treap;
        answer.first->value=node->value;
        answer.first->priority=node->priority;
        answer.first->reversed=false;
        answer.first->left=node->left;
        answer.first->right=split_answer.first;
        answer.second=split_answer.second;
    }
    else{
        pair<treap*,treap*> split_answer=split(node->left,size);
        answer.second=new treap;
        answer.second->value=node->value;
        answer.second->priority=node->priority;
        answer.second->reversed=false;
        answer.second->right=node->right;
        answer.second->left=split_answer.second;
        answer.first=split_answer.first;
    }
    update(answer.first);
    update(answer.second);
    return answer;
}
void join(treap *&answer,treap* first,treap* second){
    propagate(first);
    propagate(second);
    if(first==NULL){
        answer=second;
        return;
    }
    if(second==NULL){
        answer=first;
        return;
    }
    if(second->priority<first->priority){
        answer->left=first->left;
        answer->value=first->value;
        answer->priority=first->priority;
        answer->reversed=first->reversed;
        join(answer->right,first->right,second);
    }
    else{
        answer->right=second->right;
        answer->value=second->value;
        answer->priority=second->priority;
        answer->reversed=second->reversed;
        join(answer->left,first,second->left);
    }
    update(answer);
}
void insert(treap *&node,int index,int value,int priority){
    propagate(node);
    if(node==NULL){
        node=new treap;
        node->value=value;
        node->priority=priority;
        node->left=node->right=NULL;
        node->reversed=false;
        update(node);
        return;
    }
    if(node->priority<priority){
        pair<treap*,treap*> split_answer=split(node,index);
        node->value=value;
        node->priority=priority;
        node->left=split_answer.first;
        node->right=split_answer.second;
        node->reversed=false;
        update(node);
        return;
    }
    else
        if(get_size(node->left)<index)
            insert(node->right,index-get_size(node->left)-1,value,priority);
        else
            insert(node->left,index,value,priority);
    update(node);
}
void erase(int first,int second){
    pair<treap*,treap*> split_answer=split(root,first-1);
    treap* treap1=split_answer.first;
    split_answer=split(split_answer.second,second-first+1);
    treap* treap3=split_answer.second;
    join(root,treap1,treap3);
}
int find(treap* node,int index){
    propagate(node);
    if(node==NULL)
        return -1;
    if(index==get_size(node->left)+1)
        return node->value;
    if(index<get_size(node->left)+1)
        return find(node->left,index);
    else
        return find(node->right,index-get_size(node->left)-1);
}
void reverse(int first,int second){
    treap* temp=new treap;
    pair<treap*,treap*> split_answer=split(root,first-1);
    treap* treap1=split_answer.first;
    split_answer=split(split_answer.second,second-first+1);
    treap* treap2=split_answer.first;
    reverse_node(treap2);
    treap* treap3=split_answer.second;
    join(temp,treap1,treap2);
    join(root,temp,treap3);
}
void dump(treap* node){
    propagate(node);
    if(node!=NULL){
        dump(node->left);
        printf("%d ",node->value);
        dump(node->right);
    }
}
int main(){
    freopen("secv8.in","r",stdin);
    freopen("secv8.out","w",stdout);
    int operations,is_reversed,i,index,value,first,second;
    srand(time(0));
    nil=new treap;
    root=NULL;
    char operation;
    scanf("%d%d\n",&operations,&is_reversed);
    for(i=1;i<=operations;i++){
        scanf("%c",&operation);
        if(operation=='I'){
            scanf("%d%d\n",&index,&value);
            insert(root,index-1,value,rand());
        }
        if(operation=='A'){
            scanf("%d\n",&index);
            printf("%d\n",find(root,index));
        }
        if(operation=='R'){
            scanf("%d%d\n",&first,&second);
            reverse(first,second);
        }
        if(operation=='D'){
            scanf("%d%d\n",&first,&second);
            erase(first,second);
        }
    }
    dump(root);
    return 0;
}