[NOI 2004] 郁闷的出纳员
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1503
[算法]
平衡树
时间复杂度 : O(NlogN)
[代码]
笔者的平衡树选用的是SPLAY伸展树
#include<bits/stdc++.h> using namespace std; #define MAXP 100010 int n,lower,x,delta; char op[5]; struct Splay { int total , root; Splay() { total = 0; root = 0; } struct Node { int father , son[2]; int value , cnt , size; } Tree[MAXP]; inline bool get(int x) { return Tree[Tree[x].father].son[1] == x; } inline int getsize() { return Tree[root].size; } inline bool empty() { return (!root); } inline void update(int x) { Tree[x].size = Tree[x].cnt; Tree[x].size += Tree[Tree[x].son[0]].size; Tree[x].size += Tree[Tree[x].son[1]].size; } inline void rotate(int x) { int f = Tree[x].father , g = Tree[f].father; int tmpx = get(x) , tmpf = get(f); if (!f) return; Tree[f].son[tmpx] = Tree[x].son[tmpx ^ 1]; if (Tree[x].son[tmpx ^ 1]) Tree[Tree[x].son[tmpx ^ 1]].father = f; Tree[x].son[tmpx ^ 1] = f; Tree[f].father = x; if (g) Tree[g].son[tmpf] = x; Tree[x].father = g; update(f); update(x); } inline void splay(int x) { for (int fa = Tree[x].father; (fa = Tree[x].father); rotate(x)) rotate(get(x) == get(fa) ? fa : x); root = x; } inline void insert(int x) { if (!root) { root = ++total; Tree[total].value = x; Tree[total].father = 0; Tree[total].son[0] = Tree[total].son[1] = 0; Tree[total].size = 1; Tree[total].cnt = 1; return; } int now = root; while (now > 0) { if (Tree[now].value == x) { Tree[now].cnt++; splay(now); return; } bool tmp = x > Tree[now].value; if (!Tree[now].son[tmp]) { Tree[now].son[tmp] = ++total; Tree[total].value = x; Tree[total].father = now; Tree[total].son[0] = Tree[total].son[1] = 0; Tree[total].cnt = 1; Tree[total].size = 1; splay(total); return; } else now = Tree[now].son[tmp]; } } inline int getmin() { int now = root; while (Tree[now].son[0]) now = Tree[now].son[0]; splay(now); return Tree[now].value; } inline int query(int k) { int now = root; while (now > 0) { if (k > Tree[Tree[now].son[1]].size) { k -= Tree[Tree[now].son[1]].size; if (k <= Tree[now].cnt) { splay(now); return Tree[now].value; } else { k -= Tree[now].cnt; now = Tree[now].son[0]; } } else now = Tree[now].son[1]; } } inline int erase_min() { int now = root; while (Tree[now].son[0]) now = Tree[now].son[0]; splay(now); Tree[Tree[root].son[1]].father = 0; root = Tree[now].son[1]; int tmp = Tree[now].cnt; Tree[now].cnt = Tree[now].size = Tree[now].father = 0; Tree[now].son[0] = Tree[now].son[1] = Tree[now].value = 0; return tmp; } } T; int main() { scanf("%d%d",&n,&lower); int delta = 0 , cnt = 0; while (n--) { scanf("%s%d",&op,&x); if (strcmp(op,"I") == 0) { if (x >= lower) T.insert(x - delta); } if (strcmp(op,"A") == 0) delta += x; if (strcmp(op,"S") == 0) delta -= x; while (!T.empty() && T.getmin() + delta < lower) cnt += T.erase_min(); if (strcmp(op,"F") == 0) { if (T.getsize() < x) printf("-1\n"); else printf("%d\n",T.query(x) + delta); } } printf("%d\n",cnt); return 0; }