玄关求调
查看原帖
玄关求调
1251715
Moss345512楼主2025/8/29 22:15

本蒟蒻刚学平衡树。
旋转 Treap20RE+80WA

#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
int n,m,a,k,tx,ans;
char o;
struct Trp{
    int x,num,siz,rk;
    Trp *ch[2];
    Trp(int val):x(val),num(1),siz(1){
        ch[0]=ch[1]=nullptr;
        rk=rand();
    }
    void cpt_size(){
        siz=num+(ch[0]==nullptr?0:ch[0]->siz)+(ch[1]==nullptr?0:ch[1]->siz);
    }
};
void rot(Trp *&p,int t){
    Trp *tmp=p->ch[!t];
    if(tmp==nullptr)return;
    p->ch[!t]=tmp->ch[t];
    tmp->ch[t]=p;
    p->cpt_size();
    tmp->cpt_size();
    p=tmp;
}
void insert(Trp *&p,int x){
    if(p==nullptr){
        p=new Trp(x);
        return;
    }
    if(p->x==x){
        p->num++;
        p->cpt_size();
        return;
    }
    if(p->x>x){
        insert(p->ch[0],x);
        if(p->rk>p->ch[0]->rk)rot(p,1);
        return;
    }
    if(p->x<x){
        insert(p->ch[1],x);
        if(p->rk>p->ch[1]->rk)rot(p,0);
        return;
    }
}
void del(Trp *&p){
    ans+=p->num;
    if(p->ch[0]==nullptr && p->ch[1]==nullptr){
        delete p;
        p=nullptr;
        return;
    }
    if(p->ch[0]!=nullptr && p->ch[1]==nullptr){
        Trp *tmp=p;
        p=p->ch[0];
        delete tmp;
        p->cpt_size();
        return;
    }
    if(p->ch[0]==nullptr && p->ch[1]!=nullptr){
        Trp *tmp=p;
        p=p->ch[1];
        delete tmp;
        p->cpt_size();
        return;
    }
    if(p->ch[0]!=nullptr && p->ch[1]!=nullptr){
        int t=p->ch[0]->rk>p->ch[1]->rk;
        rot(p,t);
        del(p->ch[t]);
        p->cpt_size();
        return;
    }
}
int rkf(Trp *&p,int c){
    if(p->siz<c)return -1;
    int rs=(p->ch[1]==nullptr?0:p->ch[1]->siz);
    if(rs>=c)return rkf(p->ch[1],c);
    if(rs+p->num>=c)return p->x;
    return rkf(p->ch[0],c-rs-p->num);
}
void upd(Trp *&p){
    if(p==nullptr)return;
    if(p->x+k<m){
        upd(p->ch[0]);
        upd(p->ch[1]);
        del(p);
        return;
    }
    if(p->x+k>=m){
        upd(p->ch[0]);
        p->cpt_size();
        return;
    }
}
int main(){
    Trp *trp=nullptr;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf(" %c %d",&o,&a);
        if(o=='I' && a>=m)insert(trp,a-k);
        if(o=='A')k+=a;
        if(o=='S')k-=a,upd(trp);
        if(o=='F'){
            tx=rkf(trp,a);
            if(tx==-1)printf("-1\n");
            else printf("%d\n",rkf(trp,a)+k);
        }
    }
    printf("%d",ans);
    return 0;
}
2025/8/29 22:15
加载中...