您的位置:首页 > 其它

bzoj 1503 [NOI2004]郁闷的出纳员 splay tree

2013-08-10 15:02 405 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1503

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define inf (1<<29)
const int maxn = 100010;
int sum , splaysz , tmp;
struct node {
int p,chd[2],sz,mul,v;
node (int P=0,int val=0) {
chd[0]=chd[1]=0;sz=0;mul=1;
p = P; v= val;
}
}tree[maxn];
inline void sc(int y,int x,int p) { tree[y].chd[p]=x;tree[x].p=y; }
inline void update(int x) {
tree[x].sz=tree[tree[x].chd[0]].sz+tree[tree[x].chd[1]].sz+tree[x].mul;
}
inline void rot(int x) {
int y = tree[x].p;
int w = tree[y].chd[1] == x;
sc(tree[y].p,x,tree[tree[y].p].chd[1]==y);
sc(y,tree[x].chd[w^1],w);
sc(x,y,w^1);
update(y);
update(x);
}
void splay(int x,int rt) {
while(tree[x].p!=rt) {
int y = tree[x].p;
int w = tree[y].chd[1]==x;
if(tree[y].p != rt && tree[tree[y].p].chd[w]==y) rot(y);
rot(x);
}
}
void insert(int val) {
if(tree[0].chd[0]==0) {
tree[++splaysz] = node(0,val);
tree[0].chd[0] = splaysz;
update(splaysz);
return;
}
int now = tree[0].chd[0];
while(1) {
if(val == tree[now].v) {
tree[now].mul ++;
update(now);
splay(now,0);
return;
}
int w = val > tree[now].v;
if(tree[now].chd[w]) now = tree[now].chd[w];
else {
tree[++splaysz] = node(now,val);
tree[now].chd[w]= splaysz;
update(splaysz);
splay(splaysz,0);
return;
}
}
}
void find(int pos,int k) {
if(tree[pos].sz < k) {
puts("-1");
return;
}
int x = tree[pos].chd[0];
if(tree[x].sz>=k) find(x,k);
else if(tree[x].sz+tree[pos].mul >= k) {
printf("%d\n" , tree[pos].v-tmp);
}
else find(tree[pos].chd[1],k-tree[x].sz-tree[pos].mul);
}
void del() {
int y = tree[0].chd[0];
int x = tree[y].chd[1];
sum += tree[y].sz - tree[x].sz - 1;
tree[x].p = 0; tree[0].chd[0] = x;
}
int main() {
int n , m ,x;
char ch[11];
while(cin >> n >> m) {
sum = tmp = splaysz = 0;
tree[0] = node(0 , inf);
for(int i=0;i<n;i++) {
scanf("%s%d",ch,&x);
switch(ch[0]) {
case 'I': if(x>=m) insert(x+tmp); break;
case 'S': tmp += x; insert(m+tmp-1);del();break;
case 'A': tmp -= x; break;
case 'F':
if(tree[tree[0].chd[0]].sz < x) puts("-1");
else find(tree[0].chd[0],tree[tree[0].chd[0]].sz-x+1);
break;
}
}
printf("%d\n" , sum);
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: