BZOJ1503:[NOI2004]郁闷的出纳员
浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html
浅谈\(fhq\)_\(treap\):https://www.cnblogs.com/AKMer/p/9981274.html
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1503
对于每个人都加工资,我们可以直接降低最低工资标准来判断,对于减工资,我们就加标准,那么每个人与最低标准的差值始终是正确的。
我们记一个\(now\)表示当前最低工资标准,记一个\(mn\)表示初始工资标准。那么每次进来一个工资为\(k\)的人,我们要使他与最低工资标准的差值是正确的,就应该使\(k\)加上\(now-mn\)。
而每个人与当前最低标准的差值加上初始标准,就是真实工资。
时间复杂度:\(O(nlogn)\)
空间复杂度:\(O(n)\)
\(splay\)版代码如下:
#include <cstdio>
#include <iostream>
using namespace std;
const int maxn=1e5+5;
char s[25];
int n,mn,now,tot;
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct Splay {
int tot,root;
int fa[maxn],son[maxn][2];
int siz[maxn],cnt[maxn],val[maxn];
int newnode(int v) {
val[++tot]=v;
siz[tot]=cnt[tot]=1;
return tot;
}
int find(int v) {
int u=root;
while(val[u]!=v) {
if(val[u]>v) {if(son[u][0])u=son[u][0];else break;}
if(val[u]<v) {if(son[u][1])u=son[u][1];else break;}
}
return u;
}
int t(int u) {
return son[fa[u]][1]==u;
}
void update(int p) {
siz[p]=siz[son[p][0]]+cnt[p]+siz[son[p][1]];
}
void rotate(int u) {
int ret=t(u),f=fa[u],s=son[u][ret^1];
son[f][ret]=s;if(s)fa[s]=f;son[u][ret^1]=f;
fa[u]=fa[f];if(fa[f])son[fa[f]][t(f)]=u;
fa[f]=u;update(f);update(u);
}
void splay(int u) {
while(fa[u]) {
if(fa[fa[u]]) {
if(t(fa[u])==t(u))rotate(fa[u]);
else rotate(u);
}
rotate(u);
}
root=u;
}
void ins(int v) {
if(!root) {root=newnode(v);return;}
int u=find(v);
if(val[u]==v) {siz[u]++;cnt[u]++;splay(u);return;}
fa[newnode(v)]=u;son[u][v>val[u]]=tot;
splay(tot);
}
void check() {
int u=find(now);splay(u);
if(val[u]<now) {
u=son[u][1];
while(son[u][0])u=son[u][0];
splay(u);
}
fa[son[u][0]]=0;
son[u][0]=0;update(u);
}
int get_val(int k) {
int u=root,rk=siz[u]-k+1;
if(rk<1)return -1;
while(rk) {
if(siz[son[u][0]]>=rk)u=son[u][0];
if(siz[son[u][0]]<rk&&siz[son[u][0]]+cnt[u]>=rk)break;
if(siz[son[u][0]]+cnt[u]<rk)rk-=siz[son[u][0]]+cnt[u],u=son[u][1];
}
return val[u]+mn-now;
}
}T;
int main() {
n=read(),now=mn=read();
for(int i=1;i<=n;i++) {
scanf("%s",s+1);
int k=read();
if(s[1]=='I') {
k+=now-mn;
if(k<now)continue;
T.ins(k);tot++;
}
if(s[1]=='A')now-=k;
if(s[1]=='S') {
now+=k;
T.check();
}
if(s[1]=='F')printf("%d\n",T.get_val(k));
}
printf("%d\n",tot-T.siz[T.root]);
return 0;
}
\(fhq\)_\(treap\)版代码如下:
#include <ctime>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef pair<int,int> pii;
const int maxn=1e5+5;
char s[25];
int n,m,tot,mn,now;
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
struct fhq_treap {
int tot,root;
int fix[maxn],son[maxn][2];
int siz[maxn],cnt[maxn],val[maxn];
int newnode(int v) {
val[++tot]=v;fix[tot]=rand();
siz[tot]=cnt[tot]=1;return tot;
}
int getkth(int u,int v,bool &bo,int delta) {
if(!u)return 0;int ans=0;
if(val[u]>v)ans=getkth(son[u][0],v,bo,delta);
else if(val[u]==v) {
if(delta)cnt[u]+=delta,siz[u]+=delta,bo=1;
return siz[son[u][0]];
}
else ans=siz[son[u][0]]+cnt[u]+getkth(son[u][1],v,bo,delta);
if(bo)siz[u]+=delta;return ans;
}
void update(int p) {
siz[p]=siz[son[p][0]]+cnt[p]+siz[son[p][1]];
}
pii split(int u,int rk) {
if(!rk)return make_pair(0,u);
if(rk==siz[u])return make_pair(u,0);
if(siz[son[u][0]]>=rk) {
pii tmp=split(son[u][0],rk);
son[u][0]=tmp.second,update(u);
return make_pair(tmp.first,u);
}
else {
pii tmp=split(son[u][1],rk-siz[son[u][0]]-cnt[u]);
son[u][1]=tmp.first,update(u);
return make_pair(u,tmp.second);
}
}
int merge(int a,int b) {
if(!a||!b) return a+b;
if(fix[a]>fix[b])return son[a][1]=merge(son[a][1],b),update(a),a;
else return son[b][0]=merge(a,son[b][0]),update(b),b;
}
void ins(int v) {
bool bo=0;int rk=getkth(root,v,bo,1);
if(bo)return;pii tmp=split(root,rk);
root=merge(merge(tmp.first,newnode(v)),tmp.second);
}
void check() {
bool bo=0;
int rk=getkth(root,now,bo,0);
pii tmp=split(root,rk);root=tmp.second;
}
int get_val(int k) {
int u=root,rk=siz[u]-k+1;
if(rk<1)return -1;
while(rk) {
if(siz[son[u][0]]>=rk)u=son[u][0];
if(siz[son[u][0]]<rk&&siz[son[u][0]]+cnt[u]>=rk)break;
if(siz[son[u][0]]+cnt[u]<rk)rk-=siz[son[u][0]]+cnt[u],u=son[u][1];
}
return val[u]+mn-now;
}
}T;
int main() {
srand(time(0));
n=read(),now=mn=read();
for(int i=1;i<=n;i++) {
scanf("%s",s+1);int k=read();
if(s[1]=='I') {
k+=now-mn;
if(k<now)continue;
T.ins(k);tot++;
}
if(s[1]=='A')now-=k;
if(s[1]=='S') {
now+=k;
T.check();
}
if(s[1]=='F')printf("%d\n",T.get_val(k));
}
printf("%d\n",tot-T.siz[T.root]);
return 0;
}
BZOJ1503:[NOI2004]郁闷的出纳员的更多相关文章
- [BZOJ1503][NOI2004]郁闷的出纳员
[BZOJ1503][NOI2004]郁闷的出纳员 试题描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是 ...
- bzoj1503 [NOI2004]郁闷的出纳员(名次树+懒惰标记)
1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 8705 Solved: 3027[Submit][Statu ...
- [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] 郁闷的出纳员 (treap)
Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ...
- BZOJ1503[NOI2004]郁闷的出纳员——treap
OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心 ...
- [luogu1486][bzoj1503][NOI2004]郁闷的出纳员【平衡树treap】
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- BZOJ1503: [NOI2004]郁闷的出纳员(Splay)
Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的 工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经 ...
- BZOJ1503 [NOI2004]郁闷的出纳员 splay
原文链接http://www.cnblogs.com/zhouzhendong/p/8086240.html 题目传送门 - BZOJ1503 题意概括 如果某一个员工的工资低于了min,那么,他会立 ...
- 【题解】 bzoj1503: [NOI2004]郁闷的出纳员 (Splay)
bzoj1503,懒得复制,戳我戳我 Solution: 我知不知道我是那根筋抽了突然来做splay,调了起码\(3h+\),到第二天才改出来(我好菜啊),当做训练调错吧 一个裸的splay,没啥好说 ...
随机推荐
- 企业级API设计
最近对service的API设计,在team内有些讨论,主要集中在API是足够抽象.通用好呢, 还是具体.易用好? 其实这个是要折衷的,通用的好处是以后更改API的可能性小,但坏处是想要通用,里面的字 ...
- 《UNIX环境高级编程》读书笔记 —— 文件 I/O
打开或创建一个文件 #include <fcntl.h> int open(const char *pathname, int oflag, .../*mode_t mode*/); ...
- Eclipse工程前面有个红色的感叹号的解决办法
今天从SVN下载下工程之后,编译完,发现有两个工程有个红色的感叹号,一直没找到什么原因,问百度老师,发现问题的解决办法了. 1.先在控制台上点击Problems 如果控制台没有Problems,点击工 ...
- 【转】安卓逆向(一)--Smali基础
转载自吾爱破解安卓逆向入门教程 APK的组成 文件夹 作用 asset文件夹 资源目录1:asset和res都是资源目录但有所区别,见下面说明 lib文件夹 so库存放位置,一般由NDK编译得到,常见 ...
- mongodb启动不了:提示错误信息为 child process failed, exited with error number 100
[启动mongo 副本集错误提示]: [原因分析说明]: 查询很多资料得知由于上次使用了暴力关闭系统或者DB,导致数据文件锁住. [解决办法]: 1. 在 mongo.conf 文件添加一下属性值 ...
- Python 单元测试 之setUP() 和 tearDown()
setUp:表示前置条件,它在每一个用例执行之前必须会执行一次 setUp可以理解为我们需要自动化测试时,需要打开网页窗口,输入对应测试地址,这一些属于前置条件. tearDown:表示释放资源,它在 ...
- iOS视频直播用到的协议
一 .流媒体 1 - 伪流媒体 1.1 扫盲:边下载边播放1.2 伪流媒体:视频不是实时播放的,先把视频放在数据库,再供客户端访问,比如:优酷,爱奇艺等 1.3 特点: 边下边存,文件会保存.遵守了 ...
- 2017-2018-1 20179209《Linux内核原理与分析》第七周作业
一.实验 1.1task_struct数据结构 Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息.它定义在linux-3.18.6 ...
- 【JAVA学习】struts2的action中使用session的方法
尊重版权:http://hi.baidu.com/dillisbest/item/0bdc35c0b477b853ad00efac 在Struts2里,假设须要在Action中使用session.能够 ...
- Java实参和形参与传值和传引用
实参和形参的定义: 形参出现函数定义中,在整个函数体内都可以使用,离开函数则不能使用. 实参出现在主函数中,进入被调函数后,实参变量也不能使用. 形参和实参的功能是做数据传送.发生函数调用时,主调函数 ...