【bzoj 1503】鬱悶的出納員

傳送門~

解題思路

要求維護一棵支持查後繼和第k大的splay。
代碼:

#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdio>
#include<cstdlib>
using namespace std;
int inf=1e9;
struct node{
     int key,siz;
     node *ch[2],*fa;
     node(int);
     void maintain();
     int son(){
        if(fa->ch[0]==this) return 0;
        if(fa->ch[1]==this) return 1;
        return -1;
     }
}*null=new node(0),*root,*pans;
node:: node(int _) {key=_;siz=1;ch[0]=ch[1]=fa=null;}
void node:: maintain() {siz=ch[0]->siz+ch[1]->siz+1;}
void Rotate(node* p,bool f){
    node* t=p->ch[f^1];
    p->ch[f^1]=t->ch[f];
    if(t->ch[f]!=null) t->ch[f]->fa=p;
    t->ch[f]=p;
    p->maintain();t->maintain();
    if(~p->son()) p->fa->ch[p->son()]=t;
    t->fa=p->fa;p->fa=t;
}
void splay(node* p){
    while(~p->son()){
        int dir=p->son();
        if(p->fa->son()==dir) Rotate(p->fa->fa,dir^1);
        Rotate(p->fa,dir^1);
    }
    root=p;
}
void ch(node* p,int x){
    if(p==null) return ;
    if(p->key>x) {pans=p;ch(p->ch[0],x);}
    else ch(p->ch[1],x);
}
node* Kth(node* p,int x){
    int lp=p->ch[0]->siz+1;
    if(lp==x) return p;
    else if(lp<x) return Kth(p->ch[1],x-lp);
    else return Kth(p->ch[0],x);
}
node* Insert(node* &p,int x){
    if(p==null) {p=new node(x);return p;}
    node *t;
    if(p->key<x) {t=Insert(p->ch[1],x);p->ch[1]->fa=p;}
    else {t=Insert(p->ch[0],x);p->ch[0]->fa=p;}
    p->maintain();return t;
}
void Clear(node* &p){
    if(p==null) return ;
    Clear(p->ch[0]);
    Clear(p->ch[1]);
    delete(p);p=null;
}
void dfs(node *p){
    if(p==null) return ; 
    dfs(p->ch[0]);
    cout<<p->key<<" ";
    dfs(p->ch[1]);
}
int n,tot,c;
int main(){
    int x,zans=0;
    char opt[10];
    scanf("%d%d",&n,&c);
    null->siz=0;root=new node(inf);
    null->ch[0]=null->ch[1]=null->fa=null;
    for(int i=1;i<=n;i++){
        node* t;
        scanf("%s%d",opt,&x);
        if(opt[0]=='A') tot+=x;
        else if(opt[0]=='F'){
            if(x>=root->siz) printf("-1\n");
            else {
                x=root->siz-x;
                t=Kth(root,x);splay(t);
                printf("%d\n",root->key+tot);
            }
        }
        else if(opt[0]=='I'){
            if(x<c) continue;
            x-=tot;t=Insert(root,x);
            splay(t);
        }
        else {
            tot-=x;x=c-tot-1;
            ch(root,x);splay(pans);
            zans+=root->ch[0]->siz;
            Clear(root->ch[0]);
            root->maintain();
        }
    }
    printf("%d",zans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章