您的位置:首页 > 其它

_bzoj1503 [NOI2004]郁闷的出纳员【Splay】

2016-12-10 22:20 435 查看

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1503

由于初始工资未达到下限而离开的员工不算在离开人数之内。。。坑爹。。。

然后就是写kth的时候,忘记考虑当前节点的值有可能出现了不止一次。。。

#include <cstdio>

const int maxn = 100005;

int n, min_salary, zengL, root, cnt = 1, t1, leave;
int ch[maxn][2], fa[maxn], siz[maxn], key[maxn], tm[maxn];
char opr;

inline void pushup(int x) {
siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + tm[x];
}
inline void rotate(int x) {
int y = fa[x];
if (y == ch[fa[y]][0]) {
ch[fa[y]][0] = x;
}
else {
ch[fa[y]][1] = x;
}
fa[x] = fa[y];
int dir = x == ch[y][1];
ch[y][dir] = ch[x][dir ^ 1];
fa[ch[x][dir ^ 1]] = y;
ch[x][dir ^ 1] = y;
fa[y] = x;
pushup(y);
pushup(x);
}
inline void splay(int x) {
int p;
char flag1, flag2;
while (fa[x]) {
p = fa[x];
if (!fa

) { rotate(x); } else { flag1 = p == ch[fa[p]][1]; flag2 = x == ch[p][1]; if (flag1 ^ flag2) { rotate(x); } else { rotate(p); } rotate(x); } } root = x; } inline int houji(int val) { int rt = 0, x = root; while (x && val != key[x] + zengL) { if (val < key[x] + zengL) { rt = x; x = ch[x][0]; } else { x = ch[x][1]; } } return x? x: rt; } bool ist(int x, int val, int p, int dir) { if (!x) { ++cnt; key[cnt] = val - zengL; tm[cnt] = 1; siz[cnt] = 1; fa[cnt] = p; ch[p][dir] = cnt; return true; } if (val == key[x] + zengL) { ++tm[x]; ++siz[x]; return false; } int d = val > key[x] + zengL; bool rt = ist(ch[x][d], val, x, d); pushup(x); return rt; } inline int kth(int k) { int x = root; while (k > siz[ch[x][1]] + tm[x] || k <= siz[ch[x][1]]) { if (k > siz[ch[x][1]] + tm[x]) { k -= siz[ch[x][1]] + tm[x]; x = ch[x][0]; } else { x = ch[x][1]; } } return key[x] + zengL; } int main(void) { //freopen("in.txt", "r", stdin); scanf("%d%d", &n, &min_salary); key[1] = 2000000000; siz[1] = 1; tm[1] = 1; root = 1; while (n--) { while ((opr = getchar()) < 'A'); scanf("%d", &t1); if (opr == 'I') { if (t1 >= min_salary && ist(root, t1, 0, 0)) { splay(cnt); } } else if (opr == 'A' || opr == 'S') { zengL += (opr == 'A'? t1: -t1); splay(houji(min_salary)); leave += siz[ch[root][0]]; ch[root][0] = 0; pushup(root); } else { printf("%d\n", t1 > siz[root] - 1? -1: kth(t1 + 1)); } } printf("%d\n", leave); return 0; }

[p]  

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