# 【BZOJ 1503】【NOI 2004】郁闷的出纳员

$Splay$模板题。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node {
node *ch[2], *fa;
int d, sz, sum, lazy;
bool pl() {return this->fa->ch[1] == this;}
void setc(node *r, bool c) {ch[c] = r; r->fa = this;}
void count() {sum = ch[0]->sum + ch[1]->sum + sz;}
void push() {
if (lazy != 0) {
ch[0]->lazy += lazy;
ch[1]->lazy += lazy;
ch[0]->d += lazy;
ch[1]->d += lazy;
lazy = 0;
}
}
}*ROOT, *null;
node pool[100003];
int top = 0, M, n, gone = 0;
namespace Splay{
void Build() {
null = &pool[0];
null->d = null->sz = null->sum = 0;
null->ch[0] = null->ch[1] = null->fa = null;
ROOT = null;
}
node *newnode() {
node *t = &pool[++top];
t->d = t->sz = t->sum = 0;
t->ch[0] = t->ch[1] = t->fa = null;
return t;
}
void rotate(node *r) {
node *f = r->fa; if (r == null || f == null) return;
bool c = r->pl();
if (f->fa == null) ROOT = r, r->fa = null;
else f->fa->setc(r, f->pl());
f->setc(r->ch[!c], c);
r->setc(f, !c);
f->count();
}
void update(node *r) {if (r != ROOT) update(r->fa);	r->push();}
void splay(node *r, node *tar = null) {
update(r);
for(; r->fa != tar; rotate(r))
if (r->fa->fa != tar) rotate(r->pl() == r->fa->pl() ? r->fa : r);
r->count();
}
void ins(int num) {
if (ROOT == null) {
ROOT = newnode();
ROOT->d = num;
ROOT->sz = ROOT->sum = 1;
return;
}
node *r = ROOT;
while (1) {
r->push();
int k = r->d; bool c;
if (num < k) c = 0;
else if (num > k) c = 1;
else {++r->sz; ++r->sum; splay(r); return;}
if (r->ch[c] == null) {
r->ch[c] = newnode();
r->setc(r->ch[c], c);
r->ch[c]->sz = r->ch[c]->sum = 1;
r->ch[c]->d = num;
splay(r->ch[c]);
return;
} else r = r->ch[c];
}
}
void ins2(int num) {
node *r = ROOT;	bool c;
while (1) {
r->push();
if (num <= r->d) c = 0;
else c = 1;
if (r->ch[c] == null) {
r->ch[c] = newnode();
r->setc(r->ch[c], c);
splay(r->ch[c]);
gone += ROOT->ch[0]->sum;
ROOT->ch[1]->fa = null;
ROOT = ROOT->ch[1];
return;
} else r = r->ch[c];
}
}
int kth(int k) {
node *r = ROOT;
while (r != null) {
r->push();
if (r->ch[1]->sum >= k) r = r->ch[1];
else if (r->ch[1]->sum + r->sz >= k) return r->d;
else k -= r->ch[1]->sum + r->sz, r = r->ch[0];
}
return 0;
}
}

inline int getint() {
int k = 0, fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = k * 10 + c - '0';
return k * fh;
}
int main() {
Splay::Build();
int num;
for(int i = 1; i <= n; ++i) {
char c = getchar();	while (c < 'A' || c > 'Z') c = getchar();
switch (c) {
case 'I':
if (num >= M)
Splay::ins(num);
break;
case 'A':
ROOT->d += num;
ROOT->lazy += num;
ROOT->push();
break;
case 'S':
Splay::ins2(num + M);
ROOT->d -= num;
ROOT->lazy -= num;
ROOT->push();
break;
case 'F':
if (num > ROOT->sum) puts("-1");
else printf("%d\n", Splay::kth(num));
break;
}
}
printf("%d\n", gone);
return 0;
}


NOI 2017 Bless All
posted @ 2016-04-03 11:33  abclzr  阅读(177)  评论(0编辑  收藏  举报