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;
}
拙いものと思えども、
その手に握る其れこそが、
いつか幻想を生んでいく。