HYSBZ 1503 郁闷的出纳员

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

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

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

具体对题目要求操作的处理方式看代码

#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\n");
                else
                {
                    int ans=Findx(totnow+2-k);
                    printf("%d\n",ans+add);
                }
            }
        }
        totnow=Find(inf)-2;
        printf("%d\n",totinsert-totnow);
    }
    return 0;
}

  

时间: 2024-08-28 16:29:36

HYSBZ 1503 郁闷的出纳员的相关文章

HYSBZ 1503 郁闷的出纳员 (Splay树)

题意: 作为一名出纳员,我的任务之一便是统计每位员工的工资.但是我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反之,如果心情不好,就可能把他们的工资扣除一个相同的量. 工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了. 每位员工的工资下界都是统一规定的.每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得

HYSBZ 1503 郁闷的出纳员 伸展树

题目链接: https://vjudge.net/problem/26193/origin 题目描述: 中文题面....... 解题思路: 伸展树, 需要伸展树的模板, 突然发现自己昨天看到的模板不是太好, 现在又新找了一个,  很简练, 自己将模板的实现从头到尾看了一遍, 觉得数组实现的实在是非常的巧妙, 然后自己照着敲了一遍, 边敲边看, 崩掉了.....肯定是哪里手残了, 没有必要浪费时间去改了, 有那时间不如看点别的 代码: #include <iostream> #include &

bzoj 1503郁闷的出纳员(splay)

1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 11759  Solved: 4163[Submit][Status][Discuss] Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反之

BZOJ 1503 郁闷的出纳员

Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反之,如果心情不好,就可能把他们的工资扣除一个相同的量.我真不知道除了调工资他还做什么其它事情.工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司

1503: [NOI2004]郁闷的出纳员 Treap

1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 6263  Solved: 2190[Submit][Status] Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反之,如果心情不好,就可

[BZOJ 1503] [NOI2004] 郁闷的出纳员

1503: [NOI2004] 郁闷的出纳员 Time Limit: 5 SecMemory Limit: 64 MB Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反之,如果心情不好,就可能把他们的工资扣除一个相同的量.我真不知道除了调工资他还做什么其它事情.工资的频繁调整

BZOJ 题目1503: [NOI2004]郁闷的出纳员(SBT+延迟操作)

1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 8058  Solved: 2828 [Submit][Status][Discuss] Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反

【BZOJ】【1503】 【NOI2004】郁闷的出纳员

Splay Splay的模板题吧……妥妥的序列操作= =(好像有段时间没写过这种纯数据结构题了……) 1 /************************************************************** 2 Problem: 1503 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:660 ms 7 Memory:3644 kb 8 ***********************************

bzoj 1503: [NOI2004]郁闷的出纳员 平衡树

1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 12250  Solved: 4372[Submit][Status][Discuss] Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心情好,就可能把每位员工的工资加上一个相同的量.反之