首页 > 代码库 > bzoj1503

bzoj1503

treap改了好长时间,erase写错了。。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int inf=1<<29;
int n,mn,root,delta,tot,leave;
int key[100010],cnt[100010],size[100010],p[100010];
int child[100010][2];
void update(int x)
{
    size[x]=size[child[x][0]]+size[child[x][1]]+cnt[x];
}
void rotate(int&x,int t)
{
    int y=child[x][t];
    child[x][t]=child[y][1-t];
    child[y][1-t]=x;
    update(x);
    update(y);
    x=y;
}
void insert(int&x,int k)
{
    if(x)
    {
        if(key[x]==k)
        {
            cnt[x]++;
            update(x);
            return;
        }
        int t=key[x]<k;
        insert(child[x][t],k);
        if(p[x]<p[child[x][t]]) rotate(x,t); 
        update(x);
    }
    else
    {
        tot++;
        x=tot;
        p[x]=rand();
        key[x]=k;
        cnt[x]=1;
        update(x);
    }
}
void erase(int&x,int k)
{
    if(key[x]==k)
    {
        if(!child[x][0]&&!child[x][1])
        {
            x=0;
            return;
        }
        int t=p[child[x][1]]>p[child[x][0]];
        rotate(x,t);
        erase(child[x][t^1],k);
    } else erase(child[x][key[x]<k],k);
    update(x);
}
void _erase(int x)
{
    if(x==0) return;    
    if(key[x]+delta<mn)
    {
        leave+=cnt[x];
        if(key[child[x][0]]+delta<mn) 
        {
            leave+=size[child[x][0]];
            child[x][0]=0;
            update(x);
        }
        _erase(child[x][1]);
        erase(root,key[x]);
    } 
    _erase(child[x][0]);
}
int find(int x,int k)
{
    if(k<=size[child[x][1]]) 
        return find(child[x][1],k);
    k-=size[child[x][1]]+cnt[x];
    if(k<=0) 
        return key[x];
    return find(child[x][0],k);
}
int main()
{
    p[0]=-inf;
    scanf("%d%d",&n,&mn);
    while(n--)
    {
        char s[10]; int k; scanf("%s%d",s,&k);
        if(s[0]==I)
        {
            if(k>=mn)
                insert(root,k-delta);
        }
        if(s[0]==A)
        {
            delta+=k;
        }
        if(s[0]==S)
        {
            delta-=k;
            _erase(root);
        }
        if(s[0]==F)
        {   
            if(k>size[root]) printf("-1\n"); else
                printf("%d\n",find(root,k)+delta);
        }
    }
    printf("%d\n",leave);
    return 0;
}

 

bzoj1503