bzoj 1503 [NOI2004]郁闷的出纳员 平衡树(treap/Splay)

原创 2015年11月21日 12:03:06

Description

OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?

Input

Output

输出文件的行数为F命令的条数加一。对于每条F命令,你的程序要输出一行,仅包含一个整数,为当前工资第k多的员工所拿的工资数,如果k大于目前员工的数目,则输出-1。输出文件的最后一行包含一个整数,为离开公司的员工的总数。

Sample Input

9 10
I 60
I 70
S 50
F 2
I 30
S 15
A 5
F 1
F 2

Sample Output

10
20
-1
2

HINT

I命令的条数不超过100000 A命令和S命令的总条数不超过100 F命令的条数不超过100000 每次工资调整的调整量不超过1000 新员工的工资不超过100000

Key To Problem

treap和splay都可以搞

Code

//treap
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define N 100010
using namespace std;
struct node
{
    int l,r,v,size,rnd,w;
};
node a[N];
int n,size,root,ans,min_s,delet,sum;
char s[10];

void updata(int k)
{
    a[k].size=a[a[k].l].size+a[a[k].r].size+1;
}

void lturn(int &k)
{
    int t=a[k].r;
    a[k].r=a[t].l,a[t].l=k;
    a[t].size=a[k].size,updata(k),k=t;
}

void rturn(int &k)
{
    int t=a[k].l;
    a[k].l=a[t].r,a[t].r=k;
    a[t].size=a[k].size,updata(k),k=t;
}

void insert(int &k,int x)
{
    if(k==0)
    {
        k=++size;
        a[k].v=x,a[k].size=a[k].w=1,a[k].rnd=rand();
        return ;
    }
    a[k].size++;
    if(x>a[k].v)
    {
        insert(a[k].r,x);
        if(a[a[k].r].rnd<a[k].rnd)lturn(k);
    }else
    {
        insert(a[k].l,x);
        if(a[a[k].l].rnd<a[k].rnd)rturn(k);
    }
}

int del(int &k,int x)
{
    int t=0;
    if(k==0)return 0;
    if(x>a[k].v)
    {
        t=a[a[k].l].size+1;
        k=a[k].r;
        return t+del(k,x);
    }else
    {
        t=del(a[k].l,x);
        a[k].size-=t;
        return t;
    }
}

int query(int k,int x)
{
    if(k==0)return 0;
    if(a[a[k].l].size+1==x)return a[k].v+delet;
    if(x<a[a[k].l].size+1)return query(a[k].l,x);
    else return query(a[k].r,x-a[a[k].l].size-1);
}

int main()
{
//  freopen("cashier.in","r",stdin);
//  freopen("cashier.out","w",stdout);
    cin>>n>>min_s;
    while(n--)
    {
        int x;
        scanf("%s%d",s+1,&x);
        if(s[1]=='I'&&x>=min_s)insert(root,x-delet);
        else if(s[1]=='A')delet+=x;
        else if(s[1]=='S')
        {
            delet-=x;
            sum+=del(root,min_s-delet);
        }
        else if(s[1]=='F')
        {
            if(x>a[root].size)puts("-1");
            else printf("%d\n",query(root,a[root].size-x+1));
        }
    }
    printf("%d\n",sum);
    return 0;
}
//splay
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100010
#define ls(x) tr[x].l
#define rs(x) tr[x].r
#define fa(x) tr[x].fa
using namespace std;
struct node
{
    int l,r,fa,size,v;
};
node tr[N];
int n,m,tot,root,delta,sum;

void PushUp(int x)
{
    tr[x].size=tr[ls(x)].size+tr[rs(x)].size+1;
}

void zig(int x)
{
    int y=fa(x);
    int z=fa(y);
    if(y==ls(z))ls(z)=x;
    else rs(z)=x;
    fa(x)=z,ls(y)=rs(x),fa(y)=x,fa(rs(x))=y,rs(x)=y;
    PushUp(y),PushUp(x);
    if(y==root)root=x;
}

void zag(int x)
{
    int y=fa(x);
    int z=fa(y);
    if(y==ls(z))ls(z)=x;
    else rs(z)=x;
    fa(x)=z,rs(y)=ls(x),fa(y)=x,fa(ls(x))=y,ls(x)=y;
    PushUp(y),PushUp(x);
    if(y==root)root=x;
}

void Splay(int x,int d)
{
    while(fa(x)!=d)
    {
        if(ls(fa(x))==x)zig(x);
        else zag(x);
    }
}

void insert(int x)
{
    if(!root)
    {
        root=++tot;
        tr[tot].v=x,tr[tot].size=1;
        return ;
    }
    int p=root,z;
    while(p)
    {
        z=p;
        tr[p].size++;
        if(x<tr[p].v)p=ls(p);
        else p=rs(p);
    }
    if(x<tr[z].v)ls(z)=++tot;
    else rs(z)=++tot;
    tr[tot].v=x,tr[tot].size=1,fa(tot)=z;
    Splay(tot,0);
}

int del(int &x,int f)
{
    if(!x)return 0;
    int k;
    if(tr[x].v+delta<m)
    {
        k=del(rs(x),x)+tr[ls(x)].size+1;
        tr[rs(x)].size=tr[x].size-k;
        x=rs(x),fa(x)=f;
    }else
    {
        k=del(ls(x),x);
        tr[x].size-=k;
    }
    return k;
}

int query(int x,int k)
{
    if(k<=tr[rs(x)].size)return query(rs(x),k);
    if(k==tr[rs(x)].size+1)return tr[x].v;
    return query(ls(x),k-tr[rs(x)].size-1);
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        char s[10];
        int x;
        scanf("%s%d",s,&x);
        if(s[0]=='I'&&x>=m)insert(x-delta);
        else if(s[0]=='A')delta+=x;
        else if(s[0]=='S')delta-=x,sum+=del(root,0);
        else if(s[0]=='F'&&x>tr[root].size)puts("-1");
        else if(s[0]=='F')printf("%d\n",query(root,x)+delta);
    }
    cout<<sum<<endl;
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

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

题意: 链接 方法: treap 解析: 这是本蒟蒻的第二道treap题,第二遍写的时候update,左旋右旋,插入函数都可以大概写出来了(还是得练啊),然而del  函数却被虐了,自己也想...
  • wzq_QwQ
  • wzq_QwQ
  • 2015年03月20日 13:44
  • 2302

bzoj1503 treap

1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 7114  Solved: 2506 [Submit][...
  • u012866104
  • u012866104
  • 2015年04月02日 01:27
  • 402

bzoj1503(treap)

1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 6105  Solved: 2132 [Submit][...
  • cq_phqg
  • cq_phqg
  • 2014年09月02日 14:21
  • 491

bzoj1503 splay

运用一个整体变量处理全局修改,在减工资的时候处理删除。 反正我是不会的,理解了别人的代码(改成了指针): int del(node *&u,node *f) { if(u==null)retur...
  • nikelong0
  • nikelong0
  • 2016年03月24日 11:15
  • 167

【BZOJ1503】[NOI2004]郁闷的出纳员【Splay】

【题目链接】 写的心累。。 将A操作看为降低工资底线,将S操作看为升高工资底线。那么这样就不用标记下传了。 另外一开始要加一个inf节点,不能再加个-inf节点,因为会被删掉... 写删除的时候...
  • BraketBN
  • BraketBN
  • 2016年04月05日 15:44
  • 252

BZOJ1503

1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 5654  Solved: 2005 [Submit][...
  • cymxyym
  • cymxyym
  • 2014年06月26日 19:49
  • 415

bzoj1503【NOI2004】郁闷的出纳员

Treap模板
  • AaronGZK
  • AaronGZK
  • 2015年11月21日 20:34
  • 692

bzoj1503: [NOI2004]郁闷的出纳员(伸展树)

题目传送门 基本也算入门题了。解法: 就伸展树维护一下然后加个暴力吧。代码实现:#include #include #include using namespace std; int root; ...
  • Hanks_o
  • Hanks_o
  • 2017年10月23日 19:46
  • 198

Splay+BZOJ1503

调了好久,发现两个问题: 首先插入的时候忘记把p赋给fa的孩子,还有就是pushup的时候加上一个判断 #include #include #include #include #include #...
  • u010660276
  • u010660276
  • 2015年01月26日 21:32
  • 324

bzoj1503 郁闷的出纳员

平衡树模板题
  • sdfzyhx
  • sdfzyhx
  • 2016年05月25日 23:50
  • 210
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:bzoj 1503 [NOI2004]郁闷的出纳员 平衡树(treap/Splay)
举报原因:
原因补充:

(最多只允许输入30个字)