题目传送门
基本也算入门题了。
解法:
就伸展树维护一下然后加个暴力吧。
代码实现:
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int root;
struct node {
int d,n,c,f,son[2];
} tr[110000];
int len;
void update(int x) {
int lc=tr[x].son[0],rc=tr[x].son[1];
tr[x].c=tr[lc].c+tr[rc].c+tr[x].n;
}
void add(int d,int f) {
len++;
tr[len].d=d;tr[len].n=1;tr[len].c=1;tr[len].f=f;
if(d<tr[f].d)
tr[f].son[0]=len;
else
tr[f].son[1]=len;
tr[len].son[0]=tr[len].son[1]=0;
}
void rotate(int x,int w) {
int f=tr[x].f,ff=tr[f].f;
int R,r;
R=f;
r=tr[x].son[w];
tr[R].son[1-w]=r;
if(r!=0)
tr[r].f=R;
R=ff;r=x;
if(tr[R].son[0]==f)
tr[R].son[0]=r;
else
tr[R].son[1]=r;
tr[r].f=R;
R=x;r=f;
tr[R].son[w]=r;
tr[r].f=R;
update(f);
update(x);
}
void splay(int x,int rt) {
while(tr[x].f!=rt) {
int f=tr[x].f,ff=tr[f].f;
if(ff==rt) {
if(tr[f].son[0]==x)
rotate(x,1);
else
rotate(x,0);
}
else {
if(tr[ff].son[0]==f&&tr[f].son[0]==x) {
rotate(f,1);rotate(x,1);
}
else if(tr[ff].son[1]==f&&tr[f].son[1]==x) {
rotate(f,0);rotate(x,0);
}
else if(tr[ff].son[0]==f&&tr[f].son[1]==x) {
rotate(x,0);rotate(x,1);
}
else if(tr[ff].son[1]==f&&tr[f].son[0]==x) {
rotate(x,1);rotate(x,0);
}
}
}
if(rt==0)root=x;
}
int findip(int d) {
int x=root;
while(tr[x].d!=d) {
if(d<tr[x].d) {
if(tr[x].son[0]==0)
break;
x=tr[x].son[0];
}
else {
if(tr[x].son[1]==0)
break;
x=tr[x].son[1];
}
}
return x;
}
void ins(int d) {
if(root==0) {
add(d,0);
root=len;
return ;
}
int x=findip(d);
if(tr[x].d==d) {
tr[x].n++;
update(x);
splay(x,0);
}
else {
add(d,x);
update(x);
splay(len,0);
}
}
int ans;
void del(int x) {
splay(x,0);
ans+=tr[x].n;
if(tr[x].son[0]==0&&tr[x].son[1]==0) {
root=0;
len=0;
}
else if(tr[x].son[0]==0&&tr[x].son[1]!=0) {
root=tr[x].son[1];
tr[root].f=0;
}
else if(tr[x].son[0]!=0&&tr[x].son[1]==0) {
root=tr[x].son[0];
tr[root].f=0;
}
else {
int p=tr[x].son[0];
while(tr[p].son[1]!=0)p=tr[p].son[1];
splay(p,x);
int r=tr[x].son[1],R=p;
tr[R].son[1]=r;
tr[r].f=R;
root=R;
tr[root].f=0;
update(R);
}
}
void findpaiming(int d) {
int x=findip(d);
splay(x,0);
printf("%d\n",tr[tr[x].son[0]].c+1);
}
void findshuzhi(int k) {
if(tr[root].c<k) {
printf("-1\n");
return ;
}
int x=root;
while(1) {
int lc=tr[x].son[0],rc=tr[x].son[1];
if(k<=tr[rc].c)
x=rc;
else if(k>tr[rc].c+tr[x].n) {
k-=tr[rc].c+tr[x].n;
x=lc;
}
else
break;
}
splay(x,0);
printf("%d\n",tr[x].d);
}
void findqianqu(int d) {
int x=findip(d);
splay(x,0);
if(d<=tr[x].d) {
x=tr[x].son[0];
while(tr[x].son[1]!=0)
x=tr[x].son[1];
}
printf("%d\n",tr[x].d);
}
void findhouji(int d) {
int x=findip(d);
splay(x,0);
if(tr[x].d<=d) {
x=tr[x].son[1];
while(tr[x].son[0]!=0)
x=tr[x].son[0];
}
printf("%d\n",tr[x].d);
}
int mmin,shan[110000],slen;
void zhengjia(int x,int k) {
tr[x].d+=k;
if(tr[x].son[0]!=0)
zhengjia(tr[x].son[0],k);
if(tr[x].son[1]!=0)
zhengjia(tr[x].son[1],k);
}
void jianshao(int x,int k) {
tr[x].d-=k;
if(tr[x].d<mmin)
shan[++slen]=x;
if(tr[x].son[0]!=0)
jianshao(tr[x].son[0],k);
if(tr[x].son[1]!=0)
jianshao(tr[x].son[1],k);
}
int shanchu() {
for(int i=1; i<=slen; i++)
del(shan[i]);
}
int main() {
int n,x;
char ss[5];
scanf("%d%d",&n,&mmin);
ans=0;
for(int i=1; i<=n; i++) {
scanf("%s%d",ss+1,&x);
if(ss[1]=='I') {
if(x>=mmin)ins(x);
}
else if(ss[1]=='F')
findshuzhi(x);
else if(ss[1]=='A')
zhengjia(root,x);
else if(ss[1]=='S') {
slen=0;
jianshao(root,x);
shanchu();
}
}
printf("%d\n",ans);
return 0;
}