HNOI2002 营业额统计
学了splay,我们来做一做splay的裸题吧!
这道题还是十分的简单的。首先第一天的波动值就是当天的营业额,然后其他的,每次就直接在splay里面查找前驱后继,把与当前值差值绝对值小的那个加到答案里面就行。哦,还有就是如果已经存在过这个值那么+0即可(我的找前驱后继好像不支持相同的数……所以我在插入的时候判断了一下)
其他就没啥了……splay写的不熟练就orz了。
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #include<cstring> #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) #define enter putchar('\n') #define pr pair<int,int> #define mp make_pair #define fi first #define sc second using namespace std; typedef long long ll; const int M = 100005; const int N = 10000005; const int INF = 1000000009; int read() { int ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >='0' && ch <= '9') { ans *= 10; ans += ch - '0'; ch = getchar(); } return ans * op; } struct node { int fa,ch[2],son,cnt,val; }t[M<<2]; int n,x,tot,idx,root; bool get(int x) { return t[t[x].fa].ch[1] == x; } void pushup(int x) { t[x].son = t[t[x].ch[0]].son + t[t[x].ch[1]].son + t[x].cnt; } void rotate(int x) { int y = t[x].fa,z = t[y].fa,k = get(x); t[z].ch[t[z].ch[1] == y] = x,t[x].fa = z; t[y].ch[k] = t[x].ch[k^1],t[t[y].ch[k]].fa = y; t[x].ch[k^1] = y,t[y].fa = x; pushup(x),pushup(y); } void splay(int x,int goal) { while(t[x].fa != goal) { int y = t[x].fa,z = t[y].fa; if(z != goal) (t[y].ch[0] == x) ^ (t[z].ch[0] == y) ? rotate(x) : rotate(y); rotate(x); } if(goal == 0) root = x; } bool insert(int x) { int u = root,f = 0; bool flag = 0; while(u && t[u].val != x) f = u,u = t[u].ch[x > t[u].val]; if(u) t[u].cnt++,flag = 1; else { u = ++idx; if(f) t[f].ch[x > t[f].val] = u; t[u].ch[0] = t[u].ch[1] = 0; t[u].fa = f,t[u].val = x,t[u].cnt = t[u].son = 1; } splay(u,0); return flag; } void find(int x) { int u = root; if(!u) return; while(t[u].ch[x > t[u].val] && t[u].val != x) u = t[u].ch[x > t[u].val]; splay(u,0); } int next(int x,int f) { find(x); int u = root; if((x > t[u].val && f) || (x < t[u].val && !f)) return t[u].val; u = t[u].ch[f]; while(t[u].ch[f^1]) u = t[u].ch[f^1]; return t[u].val; } int main() { n = read(); insert(INF),insert(-INF); x = read(),insert(x),tot += x; rep(i,2,n) { x = read(); if(insert(x)) continue; int a = next(x,0),b = next(x,1); tot += min(abs(x-a),abs(x-b)); // printf("#%d\n",tot); } printf("%d\n",tot); return 0; }
当你意识到,每个上一秒都成为永恒。