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

来源:互联网 发布:ubuntu安装firefox57 编辑:程序博客网 时间:2024/05/22 15:20

【题目链接】

写的心累。。


将A操作看为降低工资底线,将S操作看为升高工资底线。那么这样就不用标记下传了。

另外一开始要加一个inf节点,不能再加个-inf节点,因为会被删掉...

写删除的时候要小心,根节点的删除和子树删除不一样。

/* Pigonometry */#include <cstdio>#include <algorithm>using namespace std;const int maxn = 100005, inf = 0x3f3f3f3f;int n, lwb, delta, ans;inline int iread() {int f = 1, x = 0; char ch = getchar();for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';return f * x;}int son[maxn][2], pre[maxn], val[maxn], size[maxn];int tot1, tot2, sta[maxn], root;inline void newnode(int &x, int f, int c) {x = tot2 ? sta[tot2--] : ++tot1;son[x][0] = son[x][1] = 0;pre[x] = f;val[x] = c;size[x] = 1;}inline void pushup(int x) {size[x] = size[son[x][0]] + size[son[x][1]] + 1;}inline void init() {tot1 = tot2 = root = 0;son[0][0] = son[0][1] = pre[0] = val[0] = size[0] = 0;newnode(root, 0, inf);pushup(root);}inline void rotate(int x) {int y = pre[x], z = pre[y], type = son[y][1] == x;pre[son[y][type] = son[x][!type]] = y;pre[x] = z;if(z) son[z][son[z][1] == y] = x;pre[son[x][!type] = y] = x;pushup(y); pushup(x);}inline void splay(int x, int goal) {while(pre[x] != goal) {int y = pre[x], z = pre[y];if(z == goal) rotate(x);else if(son[z][1] == y ^ son[x][1] == x) rotate(x), rotate(x);else rotate(y), rotate(x);}if(goal == 0) root = x;}inline int find(int k) {int x = root;while(k != size[son[x][0]] + 1)if(k <= size[son[x][0]]) x = son[x][0];else k -= size[son[x][0]] + 1, x = son[x][1];return x;}inline int insert(int c) {int now = root;for(; son[now][c > val[now]]; now = son[now][c > val[now]]);newnode(son[now][c > val[now]], now, c);splay(son[now][c > val[now]], 0);return root;}inline void trash(int x) {if(!x) return;trash(son[x][0]); trash(son[x][1]);son[x][0] = son[x][1] = pre[x] = val[x] = size[x] = 0;sta[++tot2] = x;}inline void del(int c) {int x = insert(c);splay(x, 0);ans += size[son[x][0]];trash(son[x][0]);root = son[x][1];pre[root] = 0;sta[++tot2] = x;pushup(root);}inline int findwage(int k) {k = size[root] - k;int x = find(k);return val[x];}int main() {n = iread(); lwb = iread();init();while(n--) {char ch = getchar(); for(; ch < 'A' || ch > 'Z'; ch = getchar());int k = iread();if(ch == 'I') {if(k >= lwb) insert(k + delta);}else if(ch == 'A') delta -= k;else if(ch == 'S') {delta += k;del(lwb + delta);}else if(ch == 'F') {if(k > size[root] - 1) printf("-1\n");else printf("%d\n", findwage(k) - delta);}}printf("%d\n", ans);return 0;}

附暴力和mkdata

#include <cstdio>#include <algorithm>using namespace std;const int maxn = 100005;int n, lwb, tot, ans, num[maxn];inline int iread() {int f = 1, x = 0; char ch = getchar();for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';return f * x;}inline bool cmp(int a, int b) {return a > b;}int main() {freopen("cashier.in", "r", stdin); freopen("cashier.ans", "w", stdout);n = iread(); lwb = iread(); ans = 0;while(n--) {char ch = getchar(); for(; ch < 'A' || ch > 'Z'; ch = getchar());int k = iread();if(ch == 'I') {if(k >= lwb) num[++tot] = k;}else if(ch == 'A') {for(int i = 1; i <= tot; i++) num[i] += k;}else if(ch == 'S') {sort(num + 1, num + 1 + tot, cmp);for(int i = 1; i <= tot; i++) {num[i] -= k;if(num[i] < lwb) ans += tot - i + 1, tot = i - 1;}}else if(ch == 'F') {if(k > tot) printf("-1\n");else {sort(num + 1, num + 1 + tot, cmp);printf("%d\n", num[k]);}}}printf("%d\n", ans);return 0;}

#include <cstdio>#include <cstdlib>#include <ctime>using namespace std;const int maxv = 100;inline int rd(int x) {return rand() % x + 1;}int main() {srand(time(0));freopen("cashier.in", "w", stdout);int n = 30, lwb = rd(maxv);printf("%d %d\n", n, lwb);while(n--) {int opt = rd(4);if(opt == 1) printf("I %d\n", rd(maxv) - 1);else if(opt == 2) printf("A %d\n", rd(maxv) - 1);else if(opt == 3) printf("S %d\n", rd(maxv) - 1);else if(opt == 4) printf("F %d\n", rd(n + 100));}return 0;}


0 0
原创粉丝点击