luogu1486 郁闷的出纳员

treap

#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;
int n, x, minn, delta=0, ans, rot=0, sze=0, val[100005], siz[100005], cnt[100005];
int l[100005], r[100005], rnd[100005];
char s[15];
void upd(int x){
	siz[x] = siz[l[x]] + siz[r[x]] + cnt[x];
}
void lRotate(int &k){
	int t=r[k]; r[k] = l[t]; l[t] = k;
	siz[t] = siz[k]; upd(k); k = t;
}
void rRotate(int &k){
	int t=l[k]; l[k] = r[t]; r[t] = k;
	siz[t] = siz[k]; upd(k); k = t;
}
void ins(int &k, int x){
	if(!k){
		k = ++sze; l[k] = r[k] = 0; val[k] = x;
		siz[k] = cnt[k] = 1; rnd[k] = rand();
		return ;
	}
	siz[k]++;
	if(val[k]==x)	cnt[k]++;
	else if(val[k]<x){
		ins(r[k], x);
		if(rnd[r[k]]<rnd[k])	lRotate(k);
	}
	else{
		ins(l[k], x);
		if(rnd[l[k]]<rnd[k])	rRotate(k);
	}
}
int del(int &k, int x){
	if(!k)	return 0;
	if(val[k]<x){
		int t=siz[l[k]]+cnt[k]; k = r[k];
		return t+del(k, x);
	}
	else{
		int t = del(l[k], x);
		siz[k] -= t;
		return t;
	}
}
int queryNum(int k, int x){
	if(!k)	return 0;
	if(siz[l[k]]>=x)	return queryNum(l[k], x);
	else if(x>siz[l[k]]+cnt[k])	return queryNum(r[k], x-siz[l[k]]-cnt[k]);
	else return val[k];
}
int main(){
	cin>>n>>minn;
	while(n--){
		scanf("%s %d", s, &x);
		if(s[0]=='I'){
			if(x>=minn)
				ins(rot, x-delta);
		}
		if(s[0]=='A')	delta += x;
		if(s[0]=='S'){
			delta -= x;
			ans += del(rot, minn-delta);
		}
		if(s[0]=='F'){
			if(x>siz[rot])	printf("-1\n");
			else printf("%d\n", queryNum(rot, siz[rot]-x+1)+delta);
		}
	}
	printf("%d\n", ans);
	return 0;
}
posted @ 2017-12-15 20:09  poorpool  阅读(115)  评论(0编辑  收藏  举报