洛谷.1486.[NOI2004]郁闷的出纳员(Splay)
/*
BZOJ1503: 3164kb 792ms/824ms(新建节点)
洛谷 : 3.06mb 320ms/308ms(前一个要慢wtf 其实都差不多,但前者好写)
四种操作:
A:所有元素加v。直接TAG+=v即可
S:所有元素减v。TAG-=v,如果TAG<0,即可能有低于下限的人
这时下限就是MIN-TAG(TAG<0),可以查找值为MIN-TAG的元素,将其旋到根,删掉整棵左子树
如果不存在这个元素,可以插入一个值为MIN-TAG的节点,删除左子树后再删掉这一节点
删除子树直接更改对应信息即可
I:插入一个元素。注意是插入v-TAG
F:查询第k大值。可以直接做,也可以转为找第(sz-k+1)小值
1.可以通过找MIN-TAG的前驱、将前驱旋转到根来删除,代替单点插入、删除
2.扣除不只是在TAG<0时才进行删除!
比如MIN=10 v=10, TAG=5, v能插入
但是TAG-1=4>0,可是v已经要出去了
*/
#include<cstdio>
#include<cctype>
#define gc() getchar()
//#define gc()
const int N=1e5+5;
int n,MIN,TAG,SUM,size,root,t[N],fa[N],son[N][2],sz[N],cnt[N];
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=gc()) if(c=='-') f=-1;
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
inline void Update(int rt)
{
sz[rt]=sz[son[rt][0]]+sz[son[rt][1]]+cnt[rt];
}
void Rotate(int x,int &k)
{
int a=fa[x],b=fa[a],l=son[a][1]==x,r=l^1;
if(a==k) k=x;
else son[b][son[b][1]==a]=x;
fa[x]=b, fa[a]=x, fa[son[x][r]]=a;
son[a][l]=son[x][r], son[x][r]=a;
Update(a), Update(x);
}
void Splay(int x,int &k)
{
while(x!=k)
{
int a=fa[x],b=fa[a];
if(a!=k)
(son[b][1]==a^son[a][1]==x)?Rotate(x,k):Rotate(a,k);
Rotate(x,k);
}
}
void Insert(int v,int k)
{
int f=0;
while(k && t[k]!=v) f=k,k=son[k][v>t[k]];
if(k) ++sz[k],++cnt[k];
else
{
k=++size, sz[k]=cnt[k]=1, t[k]=v, fa[k]=f;
if(f) son[f][v>t[f]]=k;
}
Splay(k,root);
}
void Get_Rank(int v,int k)
{
while(t[k]!=v && son[k][v>t[k]]) k=son[k][v>t[k]];
Splay(k,root);
}
int Find_Pre(int v,int k)
{
int res=-1;
while(k)
if(t[k]>=v) k=son[k][0];
else res=k,k=son[k][1];
return res;
}
void Delete(int k)//本题特殊,直接删掉了根节点的左子树
{
if(cnt[k]>1) {--cnt[k],--sz[k]; return;}
root=son[k][1];
fa[root]=0;
}
int Rank(int v,int k)
{
if(v>sz[k]) return -1;
v=sz[k]-v+1;//转化为求第k小值
while(1)
{
if(sz[son[k][0]]<v && sz[son[k][0]]+cnt[k]>=v) return t[k]+TAG;
if(sz[son[k][0]]>=v) k=son[k][0];
else v-=sz[son[k][0]]+cnt[k],k=son[k][1];
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1486.in","r",stdin);
#endif
n=read(),MIN=read();
char s[5];int k;
while(n--)
{
scanf("%s",s),k=read();
if(s[0]=='I')
if(k>=MIN) Insert(k-TAG,root);
else ;
else if(s[0]=='A') TAG+=k;
else if(s[0]=='S')
// if((TAG-=k)<0)//WA!
{
TAG-=k;
int pre=Find_Pre(MIN-TAG,root);
if(pre==-1) continue;
Splay(pre,root);
SUM+=sz[son[pre][0]]+cnt[pre], root=son[pre][1], fa[root]=0;
// Insert(MIN-TAG,root), Get_Rank(MIN-TAG,root);
// SUM+=sz[son[root][0]],
// sz[root]-=sz[son[root][0]], fa[son[root][0]]=0, son[root][0]=0;//删除左子树
// Delete(root);
}
else printf("%d\n",Rank(k,root));
}
printf("%d",SUM);
return 0;
}
洛谷.1486.[NOI2004]郁闷的出纳员(Splay)的更多相关文章
- 洛谷P1486 [NOI2004]郁闷的出纳员(splay)
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- 洛谷P1486 [NOI2004]郁闷的出纳员 [STL,平衡树]
题目传送门 郁闷的出纳员 题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反 ...
- 洛谷 P1486 [NOI2004]郁闷的出纳员
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- 洛谷 P1486 [NOI2004]郁闷的出纳员【Treap】题解+AC代码
题目描述 OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资 ...
- 洛谷P1486 [NOI2004]郁闷的出纳员
Code: #include<cstdio> #include<algorithm> using namespace std; struct Node{ int s,val,t ...
- BZOJ 1503: [NOI2004]郁闷的出纳员 splay
1503: [NOI2004]郁闷的出纳员 Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作 ...
- NOI2004 郁闷的出纳员 Splay
郁闷的出纳员 [问题描述] OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常, ...
- BZOJ[NOI2004]郁闷的出纳员 | Splay板子题
题目: 洛谷也能评测....还有我wa了10多次的记录233 题解: 不要想得太复杂,搞一个全局变量记录一下工资的改变量Delta,这样可以等询问的时候就输出val+Delta,然后插入的时候插入x- ...
- 【BZOJ1503】 [NOI2004]郁闷的出纳员 splay
splay模板题,都快把我做忧郁了. 由于自己调两个坑点. 1.删除时及时updata 2.Kth 考虑k满足该点的条件即r->ch[1]->size+1<=k && ...
随机推荐
- 【黑客免杀攻防】读书笔记2 - 免杀与特征码、其他免杀技术、PE进阶介绍
第3章 免杀与特征码 这一章主要讲了一些操作过程.介绍了MyCCL脚本木马免杀的操作,对于定位特征码在FreeBuf也曾发表过类似工具. VirTest5.0特征码定位器 http://www.fre ...
- 【转】linux的特殊符号与正则表达式
[转]linux的特殊符号与正则表达式 第1章 linux的特殊符号 1.1 通配符 * {} 1.1.1 含义 方便查找文件 通配符是用来找文件名字的. 1.1.2 * 通过find 命令找以 . ...
- 网络常用的linux系统调用
网络之常用的Linux系统调用 下面一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数将在前面标上“*”号以示区别. 一.进程控制 fo ...
- 每天一个linux命令【转】
转自:http://www.cnblogs.com/peida/archive/2012/12/05/2803591.html 开始详细系统的学习linux常用命令,坚持每天一个命令,所以这个系列为每 ...
- oracle巡检脚本备份
重做日志生成情况,一天生成日志大小:select round(sum(blocks*block_size)/1024/1024/1024,2) BLOCK from v\$archived_log w ...
- MyBatis返回Map键值对数据
List<Map<String, String>> getMtypeList(); <select id="getMtypeList" resultT ...
- 经典SQL语句大全(转)
SQL语句参考,包含Access.MySQL 以及 SQL Server 基础 创建数据库 CREATE DATABASE database-name 删除数据库 drop database dbna ...
- 下载文件的一致性验证之MD5值校验
前几天写脚本遇到下载功能校验,一时间不到怎么校验好? 于是请教大神,大神给出方案如下: 先去了解一下你们的产品针对这个下载功能有没有做什么功能设计...然后再针对这些功能设计去设计测试用例...比如 ...
- 【前端】JS文本比较插件
一.先上效果图 二.JS代码 /** * [文本比较插件] * 传递两个参数dom1.dom2,以dom1为基准进行比较. * 0)dom1和dom2不能都为空: * 1)如果dom1不存在,则dom ...
- Ant+Jmeter自动化接口测试的部署 及 部署过程中的坑
一.环境准备: 1.Jdk1.6或以上:http://www.oracle.com/technetwork/java/javase/downloads/index.html 配置环境变量-系统变 ...