HYSBZ 1503 郁闷的出纳员

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1503

题目中新招员工工资低于下界的话不需要计算在总数内

调用各种find时需要注意需要返回什么

具体对题目要求操作的处理方式看main函数

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define lson i<<1
#define rson i<<1|1
using namespace std;
const int N=2e5+5;
const int inf=0x3f3f3f3f;
int f[N],ch[N][2],key[N],sz[N],cnt[N];
int add,tot,root;
inline void Clear(int x)
{
    f[x]=ch[x][0]=ch[x][1]=key[x]=sz[x]=cnt[x]=0;
}
inline int get(int x)
{
    return ch[f[x]][1]==x;
}
void update(int x)
{
    if (x)
    {
        sz[x]=cnt[x];
        if (ch[x][0]) sz[x]+=sz[ch[x][0]];
        if (ch[x][1]) sz[x]+=sz[ch[x][1]];
    }
}
void Rotate(int x)
{
    int fa=f[x],ff=f[fa],kind=get(x);
    ch[fa][kind]=ch[x][kind^1];f[ch[x][kind^1]]=fa;
    ch[x][kind^1]=fa;f[fa]=x;
    f[x]=ff;
    if (ff)
        ch[ff][ch[ff][1]==fa]=x;
    update(fa);
    update(x);
}
void splay(int x,int y)
{
    for(int fa;(fa=f[x])!=y;Rotate(x))
        if (f[fa]!=y)
            Rotate((get(fa)==get(x))?fa:x);
    if (y==0) root=x;
}
void Insert(int x)
{
    if (root==0)
    {
        root=++tot;
        ch[tot][0]=ch[tot][1]=f[tot]=0;
        cnt[tot]=sz[tot]=1;
        key[tot]=x;
        return;
    }
    int now=root,fa=0;
    while(1)
    {
        if (key[now]==x)
        {
            cnt[now]++;
            update(now);
            splay(now,0);
            return;
        }
        fa=now;
        now=ch[now][key[now]<x];
        if (now==0)
        {
            tot++;
            ch[tot][0]=ch[tot][1]=0;
            cnt[tot]=sz[tot]=1;
            f[tot]=fa;
            key[tot]=x;
            ch[fa][key[fa]<x]=tot;
            update(fa);
            splay(tot,0);
            return;
        }
    }
}
int Findnum(int x)//找x的下标
{
    int now=root;
    while(1)
    {
        if (key[now]>x)
            now=ch[now][0];
        else
        {
            if (key[now]==x)
            {
                splay(now,0);
                return now;
            }
            now=ch[now][1];
        }
    }
}
int Findx(int x)//找第x小的数字
{
    int now=root;
    while(1)
    {
        if (ch[now][0]&&x<=sz[ch[now][0]])
            now=ch[now][0];
        else
        {
            int t=cnt[now];
            if (ch[now][0])
                t+=sz[ch[now][0]];
            if (x<=t) return key[now];
            x-=t;now=ch[now][1];
        }
    }
}
int Find(int x)//找x是第几小
{
    int now=root,ans=0;
    while(1)
    {
        if (key[now]>x)
            now=ch[now][0];
        else
        {
            if (ch[now][0])
                ans+=sz[ch[now][0]];
            if (key[now]==x)
                return ans+1;
            ans+=cnt[now];
            now=ch[now][1];
        }
    }
}
int pre()
{
    int now=ch[root][0];
    while(ch[now][1])
        now=ch[now][1];
    return now;
}
void del(int x)
{
    Findnum(x);
    if (cnt[root]>1)
    {
        cnt[root]--;
        update(root);
        return;
    }
    if (!ch[root][0]&&!ch[root][1])
    {
        Clear(root);
        root=0;
        return;
    }
    if (!ch[root][0])
    {
        int oldroot=root;
        root=ch[oldroot][1];
        f[root]=0;
        Clear(oldroot);
        return;
    }
    if (!ch[root][1])
    {
        int oldroot=root;
        root=ch[oldroot][0];
        f[root]=0;
        Clear(oldroot);
        return;
    }
    int leftbig=pre(),oldroot=root;
    splay(leftbig,0);
    ch[root][1]=ch[oldroot][1];
    f[ch[oldroot][1]]=root;
    Clear(oldroot);
    update(root);
}
int main()
{
    int n,minn;
    while(scanf("%d%d",&n,&minn)!=EOF)
    {
        int totinsert=0,totnow;
        add=0;root=0;tot=0;
        Insert(-inf);
        Insert(inf);
        while(n--)
        {
            char c;
            int k;
            scanf(" %c%d",&c,&k);
            if (c=='I')
            {
                if (k>=minn)
                {
                    totinsert++;
                    Insert(k-add);
                }
            }
            else if (c=='A') add+=k;
            else if (c=='S')
            {
                add-=k;
                Insert(minn-add);
                int aa=Findnum(-inf);
                int bb=Findnum(minn-add);
                splay(aa,0);
                splay(bb,aa);
                ch[ch[root][1]][0]=0;
                del(minn-add);
            }
            else
            {
                totnow=Find(inf)-2;
                if (totnow<k)
                    printf("-1
");
                else
                {
                    int ans=Findx(totnow+2-k);
                    printf("%d
",ans+add);
                }
            }
        }
        totnow=Find(inf)-2;
        printf("%d
",totinsert-totnow);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/bk-201/p/7399778.html