FHQtreap(我有个绝妙的理解方法,但课的时间不够[doge])

FHQtreap板子(P1486 [NOI2004] 郁闷的出纳员

会了FHQ,treap什么的就忘了吧......

#include<bits/stdc++.h>
using namespace std;
struct FHQ
{
    int v,w,size,l,r;
}t[300005];
int root,k,n,_min,tot,add,x,y,ans,cnt;
char ch;
int newnode(int k)
{
    ++tot;
    if(!root)root=1;
    t[tot].size=1,t[tot].v=k,t[tot].w=rand();
    return tot;
}
void update(int now)
{
    t[now].size=t[t[now].l].size+t[t[now].r].size+1;
}
int merge(int x,int y)
{
    if(!x||!y)return x+y;
    if(t[x].w<t[y].w)
    {
        t[x].r=merge(t[x].r,y);
        update(x);
        return x;
    }
    else
    {
        t[y].l=merge(x,t[y].l);
        update(y);
        return y;
    }
}
void split(int now,int val,int &x,int &y)
{
    if(!now){x=y=0;return;}
    if(t[now].v<val)
    {
        x=now;
        split(t[now].r,val,t[now].r,y);
    }
    else
    {
        y=now;
        split(t[now].l,val,x,t[now].l);    
    }
    update(now);
}
void change(int now,int k)
{
    if(!now)return; 
    t[now].v+=k;
    change(t[now].l,k);
    change(t[now].r,k);
}
int find(int now,int k)
{
    if(t[t[now].l].size==k-1)return now;
    if(t[t[now].l].size>k-1)return find(t[now].l,k);
    if(t[t[now].l].size<k-1)return find(t[now].r,k-t[t[now].l].size-1);
}
void pp()
{
    cout<<root<<endl;
    for(int i=1;i<=tot;i++) cout<<setw(2)<<i<<' ';
    cout<<endl;
    for(int i=1;i<=tot;i++) cout<<setw(2)<<t[i].v<<' ';
    cout<<endl;
    for(int i=1;i<=tot;i++) cout<<setw(2)<<t[i].l<<' ';
    cout<<endl;
    for(int i=1;i<=tot;i++) cout<<setw(2)<<t[i].r<<' ';
    cout<<endl;
    for(int i=1;i<=tot;i++) cout<<setw(2)<<t[i].size<<' ';
    cout<<endl<<endl;
}
int main()
{
    srand(114514);
    cin>>n>>_min;
    for(int i=1;i<=n;i++)
    {
        cin>>ch;
        if(ch=='I')
        {
            cin>>k;
            if(k<_min)continue;
            split(root,k,x,y);
            root=merge(merge(x,newnode(k)),y);
        } 
        if(ch=='A')
        {
            cin>>k;
            change(root,k); 
        }
        if(ch=='S')
        {
            cin>>k;
            change(root,-k);
            split(root,_min,x,y);
            ans+=t[x].size;
            root=y;
        }
        if(ch=='F')
        {
            cin>>k;
            if(t[root].size<k)
            {
                cout<<-1<<endl;
                continue;
            }
            cout<<t[find(root,tot-ans-k+1)].v<<endl;
        }
        ///pp();
    }
    cout<<ans;
    return 0;
}

 

posted @ 2021-09-17 16:53  T_X蒻  阅读(41)  评论(0编辑  收藏  举报