Cod sursa(job #1779208)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 14 octombrie 2016 22:35:58
Problema Secv8 Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.39 kb
#include <cstdio>
#include <cctype>
#include <ctime>
#include <cstdlib>

#define BUF_SIZE 1<<17

struct node{
    int s, id, pri;
    bool lazy;
    node *st, *dr;
    node(int _id){
        id=_id;
        if(_id) pri=rand();
        else pri=-1;
        lazy=0;
        s=1;
        st=dr=NULL;
    }
}*root;

int poz, id;

int pos=BUF_SIZE;
char buf[BUF_SIZE];
FILE *fin, *fout;

inline char nextch(){
    if(pos==BUF_SIZE) fread(buf, BUF_SIZE, 1, fin), pos=0;
    return buf[pos++];
}

inline int read(){
    int x=0;
    char ch=nextch();
    while(!isdigit(ch)) ch=nextch();
    while(isdigit(ch)){
        x=10*x+ch-'0';
        ch=nextch();
    }
    return x;
}

inline void propag(node *n){
    if(n->lazy){
        node *aux=n->st;
        n->st=n->dr;
        n->dr=aux;
        if(n->st!=NULL) n->st->lazy^=1;
        if(n->dr!=NULL) n->dr->lazy^=1;
        n->lazy=0;
    }
}

inline void refresh(node *n){
    n->s=1;
    if(n->st!=NULL) n->s+=n->st->s;
    if(n->dr!=NULL) n->s+=n->dr->s;
}

node *rotSt(node *n){
    node *aux=n->st;
    propag(aux);
    n->st=aux->dr;
    aux->dr=n;
    refresh(n);
    refresh(aux);
    return aux;
}

node *rotDr(node *n){
    node *aux=n->dr;
    propag(aux);
    n->dr=aux->st;
    aux->st=n;
    refresh(n);
    refresh(aux);
    return aux;
}

node *balance(node *n){
    if((n->st!=NULL)&&(n->st->pri<n->pri)) return rotSt(n);
    else if((n->dr!=NULL)&&(n->dr->pri<n->pri)) return rotDr(n);
    else{
        refresh(n);
        return n;
    }
}

node *baga(node *n){
    if(n==NULL){
        n=new node(id);
        return n;
    }else{
        propag(n);
        if(n->st==NULL){
            if(poz==0) n->st=baga(n->st);
            else{
                poz--;
                n->dr=baga(n->dr);
            }
        }else if(poz<=n->st->s) n->st=baga(n->st);
        else{
            poz-=1+n->st->s;
            n->dr=baga(n->dr);
        }
        return balance(n);
    }
}

node *scoate(node *n){
    if(n==NULL) return NULL;
    else if((n->st==NULL)&&(n->dr==NULL)){
        delete n;
        return NULL;
    }else{
        propag(n);
        node *aux;
        if(n->st==NULL){
            aux=rotDr(n);
            aux->st=scoate(aux->st);
        }else if(n->dr==NULL){
            aux=rotSt(n);
            aux->dr=scoate(aux->dr);
        }else if(n->dr->pri<n->st->pri){
            aux=rotDr(n);
            aux->st=scoate(aux->st);
        }else{
            aux=rotSt(n);
            aux->dr=scoate(aux->dr);
        }
        return balance(aux);
    }
}

int query(node *n){
    propag(n);
    if(n->st==NULL){
        if(poz==1) return n->id;
        else{
            poz--;
            return query(n->dr);
        }
    }else if(poz<=n->st->s) return query(n->st);
    else if(poz==n->st->s+1) return n->id;
    else{
        poz-=1+n->st->s;
        return query(n->dr);
    }
}

void sterge(node *n){
    if(n!=NULL){
        sterge(n->st);
        sterge(n->dr);
        delete n;
    }
}

void go(node *n){
    if(n!=NULL){
        go(n->st);
        fprintf(fout, "%d ", n->id);
        go(n->dr);
    }
}

int main(){
    srand(time(NULL));
    fin=fopen("secv8.in", "r");
    fout=fopen("secv8.out", "w");
    int n=read();
    int l=read();
    l=0;
    for(int i=0; i<n; i++){
        char ch=nextch();
        if(ch=='I'){
            poz=read()-1;
            id=read();
            root=baga(root);
            l++;
        }else if(ch=='A'){
            poz=read();
            fprintf(fout, "%d\n", query(root));
        }else if(ch=='R'){
            int a=read();
            int b=read();
            id=0;
            if((1<a)&&(b<l)){
                poz=a-1;
                root=baga(root);
                poz=b-a+1;
                root->dr=baga(root->dr);
                root->dr->st->lazy^=1;
                root->dr=scoate(root->dr);
                root=scoate(root);
            }else if(1<a){
                poz=a-1;
                root=baga(root);
                root->dr->lazy^=1;
                root=scoate(root);
            }else if(b<l){
                poz=b;
                root=baga(root);
                root->st->lazy^=1;
                root=scoate(root);
            }else root->lazy^=1;
        }else if(ch=='D'){
            int a=read();
            int b=read();
            id=0;
            if((1<a)&&(b<l)){
                poz=a-1;
                root=baga(root);
                poz=b-a+1;
                root->dr=baga(root->dr);
                node *aux=root->dr;
                sterge(aux->st);
                root->dr=aux->dr;
                delete aux;
                root=scoate(root);
            }else if(1<a){
                poz=a-1;
                root=baga(root);
                node *aux=root;
                sterge(aux->dr);
                root=root->st;
                delete aux;
            }else if(b<l){
                poz=b;
                root=baga(root);
                node *aux=root;
                sterge(aux->st);
                root=root->dr;
                delete aux;
            }else{
                sterge(root);
                root=NULL;
            }
            l-=b-a+1;
        }else return 1;
    }
    go(root);
    fclose(fin);
    fclose(fout);
    return 0;
}