题意
给出一个下限 l i m i t limit limit,需要一种数据结构 T T T 支持以下 3 种操作
- 向 T T T 中插入一个数 X X X,如果 X X X 小于 l i m i t limit limit 则不插入
- T T T中 所有数都加上/减去 X X X,并删去 T T T 中小于 l i m i t limit limit 的数
- 查询 T T T 中第 X X X 大
对于每个操作 3 输出答案,如果 T T T中少于 X X X 个数则输出-1
最后一行输出一共删去了几个数
题解
可以用 fhq treap 来维护,对于减少操作就把小于 X X X的子树拆除来,答案加上其大小并删除,对于加减操作可以用个变量 tag 来缓存,并动态改变limit大小,这样对于操作 1 就可以只变化插入值 X 而不改变整棵树
#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<list>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#include<random>
using namespace std;
#include<ext/pb_ds/priority_queue.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
#include<ext/rope>
using namespace __gnu_cxx;
#define int long long
#define PI acos(-1.0)
#define eps 1e-9
#define lowbit(a) ((a)&-(a))
#define mid ((l+r)>>1)
#define mem(x,y) memset(x,y,sizeof x)
const int mod = 1e9+7;
int qpow(int a,int b){
int ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
const int INF = 0x3f3f3f3f;
const int N = 1e6+10;
int n,lmt,tag,ans;
struct node{
int l,r;
int w,key,sz;
}fhq[N];
int root,cnt,x,y,z;
mt19937 rng(233);
void update(int now){fhq[now].sz=fhq[fhq[now].l].sz+fhq[fhq[now].r].sz+1;}
int newnode(int val){
fhq[++cnt]={0,0,val,rng(),1}; return cnt;
}
void split(int now,int val,int &x,int &y){
if(!now)x=y=0;
else{
if(fhq[now].w<=val)x=now,split(fhq[now].r,val,fhq[now].r,y);
else y=now,split(fhq[now].l,val,x,fhq[now].l);
update(now);
}
}
int merge(int x,int y){
if(!x||!y) return x|y;
if(fhq[x].key>fhq[y].key){
fhq[x].r=merge(fhq[x].r,y),update(x);
return x;
}
else{
fhq[y].l=merge(x,fhq[y].l),update(y);
return y;
}
}
void ins(int val){
split(root,val,x,y);
root=merge((merge(x,newnode(val))),y);
}
void up(){
split(root,lmt-1,x,y);
ans+=fhq[x].sz,root=y;
}
int ask(int rank){
if(rank>fhq[root].sz)return -1; rank=fhq[root].sz-rank+1;
int now=root;
while(now){
if(fhq[fhq[now].l].sz+1==rank)break;
else if(fhq[fhq[now].l].sz>=rank)now=fhq[now].l;
else rank-=fhq[fhq[now].l].sz+1,now=fhq[now].r;
}
return fhq[now].w-tag;
}
#define endl '\n'
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>lmt;
while(n--){
char op; int val; cin>>op>>val;
if(op=='I')if(val+tag>=lmt)ins(val+tag),up();
if(op=='A')tag-=val,lmt-=val;
if(op=='S')tag+=val,lmt+=val,up();
if(op=='F')cout<<ask(val)<<endl;
}
cout<<ans<<endl;
}