版权声明:欢迎转载!请注明出处!qwq https://blog.csdn.net/g21glf/article/details/86569318
传送门
【题目分析】
说是Splay的板题。。。orz谁来拯救常数巨大的我qwq
其实就是平衡树维护查询区间k大,统计比lim小的数个数,至于全体的加减可以直接用一个标记来搞定。
反正按题意弄就行了qwq
【代码~】
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
int n,lim;
int add,lef;
int rt,tot,pre;
int fa[MAXN],ch[MAXN][2],siz[MAXN],val[MAXN],cnt[MAXN];
int Read(){
int i=0,f=1;
char c;
for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar());
if(c=='-')
f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar())
i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
void push_up(int root){
siz[root]=siz[ch[root][0]]+siz[ch[root][1]]+cnt[root];
}
int which(int x,int y){
return ch[y][1]==x;
}
void rotate(int x){
int y=fa[x],z=fa[y];
int l,r;
if(!which(x,y))
l=0;
else
l=1;
r=l^1;
if(z){
if(!which(y,z)){
ch[z][0]=x;
}
else{
ch[z][1]=x;
}
}
fa[x]=z;
fa[y]=x;
fa[ch[x][r]]=y;
ch[y][l]=ch[x][r];
ch[x][r]=y;
push_up(y);
}
void splay(int x,int k){
int y,z;
while(fa[x]!=k){
y=fa[x],z=fa[y];
if(z!=k){
if(!which(y,z)^!which(x,y))
rotate(x);
else
rotate(y);
}
rotate(x);
}
if(k==0)
rt=x;
push_up(x);
}
void build_new(int x){
if(!rt){
rt=++tot;
val[tot]=x;
siz[tot]=1;
cnt[tot]=1;
return ;
}
int now=rt;
while(1){
siz[now]++;
if(val[now]==x){
cnt[now]++;
return ;
}
int y=ch[now][x>val[now]];
if(!y){
tot++;
val[tot]=x;
cnt[tot]=1;
siz[tot]=1;
fa[tot]=now;
ch[now][x>val[now]]=tot;
now=tot;
break;
}
now=y;
}
splay(now,0);
}
void query_pre(int x,int k){
if(!x)
return ;
if(val[x]<k){
pre=x;
query_pre(ch[x][1],k);
}
else{
query_pre(ch[x][0],k);
}
}
void push_add(int key){
int x=lim-key;
pre=-1;
query_pre(rt,x);
if(pre==-1)
return ;
splay(pre,0);
lef+=siz[ch[pre][0]]+cnt[pre];
rt=ch[pre][1];
fa[ch[pre][1]]=0;
}
int query_kth(int x,int k){
if(!x)
return -1;
if(siz[ch[x][1]]>=k)
return query_kth(ch[x][1],k);
if(siz[ch[x][1]]+cnt[x]>=k)
return val[x]+add;
return query_kth(ch[x][0],k-siz[ch[x][1]]-cnt[x]);
}
int main(){
n=Read(),lim=Read();
while(n--){
char cz[5];
scanf("%s",cz);
if(cz[0]=='A'){
int x=Read();
add+=x;
}
if(cz[0]=='S'){
int x=Read();
add-=x;
push_add(add);
}
if(cz[0]=='F'){
int k=Read();
cout<<query_kth(rt,k)<<'\n';
}
if(cz[0]=='I'){
int x=Read();
if(x<lim)
continue;
build_new(x-add);
}
}
cout<<lef<<'\n';
return 0;
}