[BZOJ1861][Zjoi2006]Book 书架

原题地址

以极其缓慢的速度A题中…

快要开学辣预定计划还没完成怎么办OLZ…

AC code:

#include <cstdio>
#include <cstdlib>
const int N=80010;
int n,m;

struct nod{
    int num,size,fix;
    nod *lc,*rc,*pr;
}pool[N],*pt[N],*NIL;

struct Treap{
    nod *root;

    Treap(){
        root=NIL=&pool[0];
    }

    void update(nod *p){
        p->size=p->lc->size+p->rc->size+1;
    }
    nod* merge(nod *p1,nod *p2){
        if(p1==NIL) return p2;
        if(p2==NIL) return p1;
        if(p1->fix>p2->fix){
            nod *p3=merge(p1->rc,p2);
            p3->pr=p1;p1->rc=p3;
            update(p1);
            return p1;
        }
        nod *p3=merge(p1,p2->lc);
        p3->pr=p2;p2->lc=p3;
        update(p2);
        return p2;
    }
    void split(nod *p,nod *&p1,nod *&p2,int k){
        if(p==NIL){
            p1=p2=NIL;
            return ;
        }
        if(p->lc->size+1>k){
            split(p->lc,p1,p2,k);
            p->lc=p->pr=NIL;
            update(p);
            p2=merge(p2,p);
        }
        else{
            split(p->rc,p1,p2,k-p->lc->size-1);
            p->rc=p->pr=NIL;
            update(p);
            p1=merge(p,p1);
        }
    }
    int getrank(nod *p){
        int k=p->lc->size+1;
        while(p->pr!=NIL){
            if(p->pr->rc==p) k+=p->pr->lc->size+1;
            p=p->pr;
        }
        return k;
    }
    void insert(int k,nod *p){
        nod *p1,*p2;
        split(root,p1,p2,k);
        root=merge(merge(p1,p),p2);
    }
    void erase(int k){
        nod *p1,*p2,*p3,*p4;
        split(root,p1,p2,k-1);
        split(p2,p3,p4,1);
        root=merge(p1,p4);
    }
    void getkth(int k){
        nod *p1,*p2,*p3,*p4;
        split(root,p1,p2,k-1);
        split(p2,p3,p4,1);
        printf("%d\n",p3->num);
        root=merge(merge(p1,p3),p4);
    }
};

int main(){
    scanf("%d%d",&n,&m);
    Treap T;
    for(int i=1;i<=n;i++){
        pt[i]=&pool[i];
        pt[i]->lc=pt[i]->rc=pt[i]->pr=NIL;
        pt[i]->num=i;pt[i]->size=1;pt[i]->fix=rand();
    }
    for(int i=1;i<=n;i++){
        int t;
        scanf("%d",&t);
        T.insert(i-1,pt[t]);
    }
    for(int i=1;i<=m;i++){
        int  x,y;
        char s[11];
        scanf("%s%d",s,&x);
        if(s[0]=='T'){
            T.erase(T.getrank(pt[x]));
            T.insert(0,pt[x]);
        }
        else if(s[0]=='B'){
            T.erase(T.getrank(pt[x]));
            T.insert(n-1,pt[x]);
        }
        else if(s[0]=='I'){
            scanf("%d",&y);
            int k=T.getrank(pt[x]);
            T.erase(k);
            T.insert(k-1+y,pt[x]);
        }
        else if(s[0]=='A') printf("%d\n",T.getrank(pt[x])-1);
        else T.getkth(x);
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值