【BZOJ1503】 [NOI2004]郁闷的出纳员 splay
splay模板题,都快把我做忧郁了。
由于自己调两个坑点。
1.删除时及时updata
2.Kth 考虑k满足该点的条件即r->ch[1]->size+1<=k && r->ch[1]->size+r->num>=k
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct SplayNode
{
SplayNode *fa,*ch[];
SplayNode();
int data,size,num;
int chr() {return this==fa->ch[];}
void updata() { size=ch[]->size+ch[]->size+num;}
}*null;
SplayNode::SplayNode() {fa=ch[]=ch[]=null; num=; size=;}
int n,minn;
inline int read() {int ans=; char c; while ((c=getchar())==' ' || c=='\r' || c=='\n'); ans=c-''; while (isdigit(c=getchar())) ans=ans*+c-''; return ans;}
namespace Splay
{
SplayNode *Root;
void MakeTree()
{
null=new SplayNode;
*null=SplayNode();
Root=null;
}
void rotate(SplayNode *x)
{
SplayNode *r=x->fa;
if (x==null || r==null) return;
int t=x->chr();
r->ch[t]=x->ch[t^];
r->ch[t]->fa=r;
if (r->fa==null) Root=x;
else r->fa->ch[r->chr()]=x;
x->fa=r->fa;
x->ch[t^]=r;
r->fa=x;
r->updata();
x->updata();
}
void splay(SplayNode *x,SplayNode *y)
{
for (;x->fa!=y;rotate(x))
if (x->fa->fa!=y)
if (x->chr()==x->fa->chr()) rotate(x->fa);
else rotate(x);
}
void insert(int v)
{
SplayNode *r=Root;
if (Root==null)
{
Root=new SplayNode;
Root->data=v;
Root->updata();
return;
}
if (Root->data==v)
{
Root->num++;
Root->updata();
return;
}
while (r->ch[r->data<v]!=null)
{
r=r->ch[r->data<v];
if (r->data==v)
{
r->num++;
splay(r,null);
return;
}
}
r->ch[r->data<v]=new SplayNode;
r->ch[r->data<v]->data=v;
r->ch[r->data<v]->fa=r;
splay(r->ch[r->data<v],null);
}
void pre(SplayNode *x,int v,SplayNode *&ans)
{
if (x==null) return;
else if (x->data<v)
{
if (ans->data<x->data || ans==null) ans=x;
pre(x->ch[],v,ans);
}else pre(x->ch[],v,ans);
}
void suc(SplayNode *x,int v,SplayNode *&ans)
{
if (x==null) return;
else if (x->data>v)
{
if (ans->data>x->data || ans==null) ans=x;
suc(x->ch[],v,ans);
}else suc(x->ch[],v,ans);
}
void del(int v)
{
SplayNode *q=null; pre(Root,v,q);
SplayNode *p=null; suc(Root,v,p);
if (q==null && p==null)
{
if (Root->num==) Root=null;
else Root->num--,Root->updata();
return;
}
if (q==null)
{
splay(p,null);
if (p->ch[]->num==) p->ch[]=null,p->updata();
else p->ch[]->num--,splay(p->ch[],null);
return;
}
if (p==null)
{
splay(q,null);
if (q->ch[]->num==) p->ch[]=null,p->updata();
else p->ch[]->num--,splay(p->ch[],null);
return;
}
splay(q,null);
splay(p,q);
if (p->ch[]->num==) p->ch[]=null,p->updata();
else p->ch[]->num--,splay(p->ch[],null);
return;
}
SplayNode *Kth(int k)
{
SplayNode *r=Root;
while (r!=null)
{
if (k<=r->ch[]->size) r=r->ch[];
else if (r->ch[]->size+<=k && r->ch[]->size+r->num>=k) return r;
else
{
k-=r->ch[]->size+r->num;
r=r->ch[];
}
}
return r;
}
SplayNode *find(int v)
{
SplayNode *r=Root;
while (r!=null)
{
if (r->data==v)
{
splay(r,null);
return r;
}
r=r->ch[r->data<v];
}
return null;
}
}
int main()
{
//freopen("1503.out","w",stdout);
int ans=,dell=,ans1=;
Splay::MakeTree();
n=read(); minn=read();
while (n--)
{
char s[];
int x;
scanf("%s",s); x=read();
if (s[]=='I') if (x>=minn) Splay::insert(x-dell),ans++;
if (s[]=='A') dell+=x;
if (s[]=='S')
{
dell-=x;
Splay::insert(minn-dell);
SplayNode *r=Splay::find(minn-dell);
// Splay::splay(r,null);
if (r->ch[]!=null) ans1+=r->ch[]->size,ans-=r->ch[]->size;
while (r->ch[]!=null)
{
Splay::del(r->ch[]->data);
Splay::splay(r,null);
}
Splay::del(minn-dell);
}
if (s[]=='F')
if (x>ans) puts("-1");
else
printf("%d\n",Splay::Kth(x)->data+dell);
}
printf("%d\n",ans1);
return ;
}
Description
OIER公司是一家大型专业化软件公司,有着数以万计的员工。作为一名出纳员,我的任务之一便是统计每位员工的工资。这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资。如果他心情好,就可能把每位员工的工资加上一个相同的量。反之,如果心情不好,就可能把他们的工资扣除一个相同的量。我真不知道除了调工资他还做什么其它事情。工资的频繁调整很让员工反感,尤其是集体扣除工资的时候,一旦某位员工发现自己的工资已经低于了合同规定的工资下界,他就会立刻气愤地离开公司,并且再也不会回来了。每位员工的工资下界都是统一规定的。每当一个人离开公司,我就要从电脑中把他的工资档案删去,同样,每当公司招聘了一位新员工,我就得为他新建一个工资档案。老板经常到我这边来询问工资情况,他并不问具体某位员工的工资情况,而是问现在工资第k多的员工拿多少工资。每当这时,我就不得不对数万个员工进行一次漫长的排序,然后告诉他答案。好了,现在你已经对我的工作了解不少了。正如你猜的那样,我想请你编一个工资统计程序。怎么样,不是很困难吧?
Input

Output
输出文件的行数为F命令的条数加一。对于每条F命令,你的程序要输出一行,仅包含一个整数,为当前工资第k多的员工所拿的工资数,如果k大于目前员工的数目,则输出-1。输出文件的最后一行包含一个整数,为离开公司的员工的总数。
Sample Input
I 60
I 70
S 50
F 2
I 30
S 15
A 5
F 1
F 2
Sample Output
20
-1
2
HINT
I命令的条数不超过100000 A命令和S命令的总条数不超过100 F命令的条数不超过100000 每次工资调整的调整量不超过1000 新员工的工资不超过100000
Source
【BZOJ1503】 [NOI2004]郁闷的出纳员 splay的更多相关文章
- BZOJ1503 [NOI2004]郁闷的出纳员 splay
原文链接http://www.cnblogs.com/zhouzhendong/p/8086240.html 题目传送门 - BZOJ1503 题意概括 如果某一个员工的工资低于了min,那么,他会立 ...
- bzoj1503[NOI2004]郁闷的出纳员——Splay
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1503 好奇怪呀!为什么而TLE? 各种修改终于卡时过了.可是大家比我快多了呀?难道是因为自己 ...
- [BZOJ1503][NOI2004]郁闷的出纳员
[BZOJ1503][NOI2004]郁闷的出纳员 试题描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是 ...
- BZOJ 1503: [NOI2004]郁闷的出纳员 splay
1503: [NOI2004]郁闷的出纳员 Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作 ...
- [BZOJ1503][NOI2004]郁闷的出纳员 无旋Treap
1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec Memory Limit: 64 MB Description OIER公司是一家大型专业化软件公司,有着数以万计的员 ...
- bzoj1503: [NOI2004]郁闷的出纳员(伸展树)
1503: [NOI2004]郁闷的出纳员 题目:传送门 题解: 修改操作一共不超过100 直接暴力在伸展树上修改 代码: #include<cstdio> #include<cst ...
- bzoj1503 [NOI2004]郁闷的出纳员(名次树+懒惰标记)
1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 8705 Solved: 3027[Submit][Statu ...
- NOI2004 郁闷的出纳员 Splay
郁闷的出纳员 [问题描述] OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常, ...
- BZOJ1503: [NOI2004]郁闷的出纳员(Splay)
Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的 工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经 ...
随机推荐
- IE文档版本和文档流模式
使用X-UA-Compatible来设置IE浏览器兼容模式 文件兼容性用于定义让IE如何编译你的网页.此文件解释文件兼容性,如何指定你网站的文件兼容性模式以及如何判断一个网页该使用的文件模式. < ...
- LINQ To DataSet 示例
如果在项目遇到这样的问题如:DataTable1和DataTable2需要根据一定的规则进行合并成一个DataTable3. 问题1:DataTable1不是读数据库表的结果,而是合成的数据集,因此无 ...
- shell test 數值 字符串 文件比較
數值比較 描述 n1 –eq n2 等於 n1 –gt n2 大於 n1 –ge n2 大於等於 n1 –lt n2 小於 n1 –le n2 小於等於 n1 –ne n2 不等於 字符串比較 ...
- (四)WebRTC手记之本地音频采集
转自:http://www.cnblogs.com/fangkm/p/4374668.html 上一篇博文介绍了本地视频采集,这一篇就介绍下音频采集流程,也是先介绍WebRTC原生的音频采集,再介绍C ...
- set[c++]
#include <iostream> using namespace std; #include <set> int main(int argc, const char * ...
- Android使用JNI实现Java与C之间传递数据(转)
介绍Java如何将数据传递给C和C回调Java的方法. java传递数据给C,在C代码中进行处理数据,处理完数据后返回给java.C的回调是Java传递数据给C,C需要用到Java中的某个方法,就需 ...
- CentOS安装中文支持
部分文档突然成乱码了. 解决方法: 1.安装中文支持包 # yum groupinstall "Chinese Support" 2 修改# /etc/sysconfig/i18n ...
- c++11 正则表达式基本使用
c++ 11 正则表达式 常用的方法 regex_match regex_search regex_replace 等. regex_match 要求正则表达式必须与模式串完全匹配,例如: strin ...
- 玲珑杯1007-A 八进制大数加法(实现逻辑陷阱与题目套路)
题目连接:http://www.ifrog.cc/acm/problem/1056 DESCRIPTION Two octal number integers a, b are given, and ...
- Windows服务定时执行任务
1.创建多线程类 /// <summary> /// 多线程 /// </summary> public abstract class MuliThread<T> ...