BZOJ 1503 [NOI2004]郁闷的出纳员 (Splaytree)
2014-02-13 21:29
483 查看
用Splaytree实现插入,删除一个区间,求小于某值的个数。
题意有个坑。。初始工资小于工资下届不计入离开公司的总数。。
题意有个坑。。初始工资小于工资下届不计入离开公司的总数。。
#include const int maxn = 100000+10; const int INF = 1<<30; #define lson x->ch[0] #define rson x->ch[1] #define ket (root->ch[1]->ch[0]) struct NODE { NODE *pre, *ch[2]; int val, id, sz, mark; void down() { if(mark) { if(ch[0]->pre) { ch[0]->mark += mark; ch[0]->val += mark; } if(ch[1]->pre) { ch[1]->mark += mark; ch[1]->val += mark; } mark = 0; } } void up() { sz = ch[0]->sz + ch[1]->sz + 1; } }node[maxn], *null = &node[0], *root; struct Splaytree { int top; void Rotate(NODE *x, int c) { NODE *y = x->pre; y->down(); x->down(); y->ch[!c] = x->ch[c]; if(x->ch[c] != null) x->ch[c]->pre = y; x->pre = y->pre; if(y->pre != null) y->pre->ch[ y->pre->ch[1]==y ] = x; x->ch[c] = y; y->pre = x; y->up(); } void Splay(NODE *x, NODE *go) { while(x->pre != go) { if(x->pre->pre == go) Rotate(x, x->pre->ch[0] == x); else { NODE *y = x->pre, *z = y->pre; int f = z->ch[1] == y; if(y->ch[f] == x) Rotate(y, !f); else Rotate(x, f); Rotate(x, !f); } } x->up(); if(go == null) root = x; } void RTO(int k, NODE *go) { NODE *x = root; x->down(); while(lson->sz != k) { if(lson->sz > k) x = lson; else { k -= lson->sz + 1; x = rson; } x->down(); } Splay(x, go); } void debug(NODE *x) { if(x != null) { printf("节点: %2d 左儿子: %2d 右儿子: %2d size = %2d val = %2d\n", x->id, x->ch[0]->id, x->ch[1]->id, x->sz, x->val); x->down(); debug(x->ch[0]); debug(x->ch[1]); } } NODE *newnode(int c, NODE* f=null) { NODE *x = &node[++top]; x->id = top; x->val = c; x->sz = 1; x->mark = 0; x->pre = f; lson = rson = null; return x; } void init() { null->id = null->sz = null->val = null->mark = 0; top = 0; root = newnode(-INF); root->ch[1] = newnode(INF, root); root->ch[1]->up(); root->up(); } void Insert(int c) { NODE *x = root; while(x->ch[ x->val <= c] != null) { x->down(); x = x->ch[ x->val <= c]; } x->down(); x->ch[ x->val <= c] = newnode(c, x); Splay(x->ch[x->val<=c], null); } int find_cnt(NODE *x, int c) { if(x == null) return 0; x->down(); if(x->val < c) return lson->sz + 1 + find_cnt(rson, c); else return find_cnt(lson, c); } void solve() { init(); int n, m, k; scanf("%d%d", &n, &m); int ans = 0; while(n--) { char op[2]; scanf("%s%d", op, &k); if(op[0] == 'I') { if(k >= m) Insert(k); } else if(op[0] == 'A') { root->mark += k; root->val += k; } else if(op[0] == 'S') { root->mark -= k; root->val -= k; int cnt = find_cnt(root, m); if(cnt >= 2) { ans += cnt-1; RTO(0, null); RTO(cnt, root); ket = null; root->ch[1]->up(); root->up(); } } else { if(root->sz-2 < k) puts("-1"); else { RTO(root->sz-2-k + 1, null); printf("%d\n", root->val); } } } printf("%d\n", ans); } }spt; int main(){ spt.solve(); return 0; }
相关文章推荐
- BZOJ 1503 郁闷的出纳员【NOI2004】
- bzoj1503[NOI2004]郁闷的出纳员 treap
- 【BZOJ】1503 [NOI2004]郁闷的出纳员 平衡树
- bzoj 1503: [NOI2004]郁闷的出纳员 splay
- bzoj 1503: [NOI 2004]郁闷的出纳员
- [BZOJ 1503] [NOI2004] 郁闷的出纳员
- 【BZOJ 1503】【NOI 2004】郁闷的出纳员
- bzoj 1503: [NOI2004]郁闷的出纳员 -- 权值线段树
- BZOJ1503 [NOI2004]郁闷的出纳员
- BZOJ 1503: [NOI2004]郁闷的出纳员
- bzoj 1503 [NOI2004]郁闷的出纳员 splay tree
- BZOJ 1503 郁闷的出纳员(平衡树)(NOI 2004)
- 【BZOJ 1503】[NOI2004]郁闷的出纳员 treap
- 平衡二叉树SBT(BZOJ1503[NOI2004]郁闷的出纳员)
- BZOJ 1503: [NOI2004]郁闷的出纳员
- 【平衡树】BZOJ1503(NOI2004)[郁闷的出纳员]题解
- (WA)BZOJ 1503: [NOI2004]郁闷的出纳员
- BZOJ1503 [NOI2004]郁闷的出纳员
- BZOJ1503 NOI2004 郁闷的出纳员 题解&代码
- 【BZOJ】1503: [NOI2004]郁闷的出纳员(Splay)