BZOJ 1588 营业额统计 Splay
很水的题,找一下前驱和后继
第一次写Splay,感觉非常蛋疼,而且不用指针搞各种debug不能。
他是利用伸展操作来保证平均复杂度的,不过写过Treap之后,伸展操作并不难理解= =,不过写起来感觉还是有点蛋疼的,所以这遍是仿照cxlove的写法的
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <vector> #include <map> #include <set> #include <list> #include <queue> #include <stack> #include <climits> #include <iostream> using namespace std; typedef long long LL; const int maxn = 1e6 + 10; int fa[maxn], key[maxn], ch[maxn][2], root, sz; void debug() { puts("----------debug start----------------"); for(int i = 0; i <= sz; i++) { printf("Node %d, key = %d, lch = %d, rch = %d, fa = %d\n", i, key[i], ch[i][0], ch[i][1], fa[i]); } puts("************debug end**************"); } void newNode(int &r, int father, int k) { r = ++sz; fa[r] = father; key[r] = k; ch[r][0] = ch[r][1] = 0; } void rotate(int o, int d) { int y = fa[o]; ch[y][d ^ 1] = ch[o][d]; fa[ch[o][d]] = y; if(fa[y] != 0) { ch[fa[y]][y == ch[fa[y]][1]] = o; } ch[o][d] = y; fa[o] = fa[y]; fa[y] = o; } void splay(int r, int goal) { while(fa[r] != goal) { int d = (r == ch[fa[r]][1]), y = fa[r]; if(fa[fa[r]] == goal) rotate(r, d ^ 1); else { int d1 = ch[fa[y]][1] == y; if(d == d1) { rotate(y, d ^ 1); rotate(r, d ^ 1); } else { rotate(r, d1); rotate(r, d); } } } if(goal == 0) root = r; } int insert(int val) { int r = root; while(ch[r][val > key[r]]) { if(key[r] == val) { splay(r, 0); return 0; } r = ch[r][val > key[r]]; } newNode(ch[r][val > key[r]], r, val); splay(ch[r][val > key[r]], 0); return 1; } int ask(int x, int d) { x = ch[x][d ^ 1]; while(ch[x][d]) x = ch[x][d]; return x; } int main() { int n; while(scanf("%d", &n) != EOF) { root = sz = 0; int ans = 0; newNode(root, 0, INT_MAX); insert(-INT_MAX); for(int i = 1; i <= n; i++) { int num; scanf("%d", &num); if(i == 1) { insert(num); ans += num; } else { int ret = insert(num); if(ret == 0) continue; int t1 = ask(root, 0), t2 = ask(root, 1); ans += min((LL)abs((LL)key[t1] - num), (LL)abs((LL)key[t2] - num)); } } printf("%d\n", ans); } return 0; }