题目链接

/*
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;
}

最新文章

  1. logstash日志分析的配置和使用
  2. 神经网络和Deep Learning
  3. linux下crontab命令的使用
  4. Android 调用已安装市场,进行软件评分的功能实现
  5. mysql配置详解
  6. uva 10972(边双连通分量)
  7. PostgreSQL Errors and Messages
  8. C#_wpf_userinput_数据绑定_后台对象改变,界面数据也变化
  9. NOI2008假面舞会
  10. How to install Python 2.7 and Python 3.3 on CentOS 6
  11. boost::asio 的同、异步方式
  12. Codility上的问题 (16) Omicron 2012
  13. VR全景:电商巨头的角逐
  14. 201521123001《Java程序设计》第5周学习总结
  15. windows phone 模拟器
  16. go 多维度 Map 的数据存取
  17. 调皮的HR
  18. blfs(systemd版本)学习笔记-wget的安装与配置
  19. vueJs的简单入门以及基础语法
  20. SQL 计算某月有多少天

热门文章

  1. ubuntu 的 apt-get update 出现404错误时,或者添加ppa失败时,ubuntu 版本也 end of life 了的解决方案
  2. grep基础用法
  3. CSS选择器中带点(.)怎么办?
  4. 一步步实现windows版ijkplayer系列文章之二——Ijkplayer播放器源码分析之音视频输出——视频篇
  5. centos6.5生产环境编译安装nginx-1.11.3并增加第三方模块ngx_cache_purge、nginx_upstream_check、ngx_devel_kit、lua-nginx
  6. 脚本检测CDN节点资源是否与源站资源一致
  7. vue首次赋值不触发watch
  8. Jmeter接口测试参数化实例图文示例
  9. Keepalived详解之 - LVS(IPVS)管理工具ipvsadm使用指南
  10. 区间dp的一些模式和总结