提交了50次后发现BZOJ不能用cin,cout的事情,我就是个大傻逼
Treap实现插入,删除,第k大,事实证明太久没敲是会手生的。
#include <stdio.h>
#include <queue>
#include <algorithm>
using namespace std;
struct Node {
int v,sz,r;
Node *ch[2];
};
Node *nill,*root;
queue<Node*> list;
int n,deadline,delta,quit;
unsigned ran() { static unsigned ranx = 987654321; return ranx += ranx<<2|1; }
void New_node(Node *&o,int val) {
if (list.empty()) {
Node *p = new Node[10000];
for (int i = 0; i < 10000; i ++)
list.push(p+i);
}
o = list.front(); list.pop();
o->ch[0] = o->ch[1] = nill; o->r = ran();
o->v = val; o->sz = 1;
}
void up(Node *o) { o->sz = o->ch[0]->sz + o->ch[1]->sz + 1; }
void cut(Node *o,Node *&a,Node *&b,int val) {
if (o==nill) a = b = nill;
else if (o->v>=val) {
b = o;
cut(o->ch[0],a,b->ch[0],val);
up(b);
} else {
a = o;
cut(o->ch[1],a->ch[1],b,val);
up(a);
}
}
void merge(Node *&o,Node *a,Node *b) {
if (a==nill) o = b;
else if (b==nill) o = a;
else if (a->r < b->r) {
o = b;
merge(o->ch[0],a,b->ch[0]);
up(o);
} else {
o = a;
merge(o->ch[1],a->ch[1],b);
up(o);
}
}
void ins(int val) {
if (val+delta<deadline) return;
Node *a,*b,*c;
cut(root,a,b,val);
New_node(c,val);
merge(a,a,c);
merge(root,a,b);
}
void reuse(Node *o) {
if (o==nill) return;
reuse(o->ch[0]);
reuse(o->ch[1]);
list.push(o);
}
void del() {
Node *a;
cut(root,a,root,deadline-delta);
quit += a->sz;
reuse(a);
}
int query(Node *o,int k) {
if (o->ch[0]->sz+1==k) return o->v;
if (o->ch[0]->sz>=k) return query(o->ch[0],k);
else return query(o->ch[1],k - o->ch[0]->sz - 1);
}
int main() {
scanf("%d%d",&n,&deadline);
New_node(nill,0); nill->sz = 0; root = nill;
while (n--) {
char s[13]; int k;
scanf("%s%d",s,&k);
if (s[0]=='I') ins(k-delta);
else if (s[0]=='A') delta += k;
else if (s[0]=='S') delta -= k, del();
else {
k = root->sz - k + 1;
if (k<=0) printf("-1\n");
else printf("%d\n",query(root,k)+delta);
}
}
printf("%d\n",quit);
return 0;
}