bzoj 1588营业额统计(HNOI 2002)

http://www.lydsy.com/JudgeOnline/problem.php?id=1588

 

splay  bottom-up的数组实现。

题意就是给你一组数,求每个数与在其前面且与其最相近的数的差值的绝对值。

考虑splay二叉搜索树的特性,每新插入一个节点,比它小且最靠近它的数在是左子树中的最大值,另一半同理。

 

代码借鉴自: http://blog.csdn.net/ACM_cxlove?viewmode=contents

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn = 1e5 + 10;
 6 const int inf = 0x3f3f3f3f;
 7 int pre[maxn], key[maxn], ch[maxn][2], root, size;
 8 int n;
 9 
10 void new_node(int &r, int father, int k){
11     r = ++size;
12     pre[r] = father;
13     key[r]= k;
14     ch[r][0] = ch[r][1] = 0;
15 }
16 
17 void rotate(int x, bool d){// d = 1, right rotate
18     int y = pre[x];
19     ch[y][!d] = ch[x][d];
20     pre[ch[x][d]] = y;
21     if(pre[y]) ch[pre[y]][ch[pre[y]][1] == y] = x;
22     //if y is not the root, link x with its grandparent
23     pre[x] = pre[y];
24     ch[x][d] = y;
25     pre[y] = x;
26 }
27 
28 void splay(int u, int dest){
29     //root u to root dest
30     while(pre[u] != dest){
31         if(pre[pre[u]] == dest) rotate(u, ch[pre[u]][0] == u);
32         else{
33             int y = pre[u];
34             int d = ch[pre[y]][0] == y;
35             if(ch[y][d] == u){//zig-zag
36                 rotate(u, !d);
37                 rotate(u, d);
38             }else{
39                 rotate(y, d);//zig-zig
40                 rotate(u, d);
41             }
42         }
43     }
44     if(!dest) root = u;
45 }
46 
47 int insert(int k){
48     int u = root;
49     while(ch[u][key[u] < k]){
50         if(key[u] == k) return splay(u, 0), 0;
51         u = ch[u][key[u] < k];
52     }
53     if(key[u] == k) return splay(u, 0), 0;
54     new_node(ch[u][key[u] < k], u, k);
55     splay(ch[u][key[u] < k], 0);
56     return 1;
57 }
58 
59 int get_pre(int x){
60     int tem = ch[x][0];
61     if(!tem) return inf;
62     while(ch[tem][1]) tem = ch[tem][1];
63     return key[x] - key[tem];
64 }
65 
66 int get_next(int x){
67     int tem = ch[x][1];
68     if(tem == 0) return inf;
69     while(ch[tem][0]) tem = ch[tem][0];
70     return key[tem] - key[x];
71 }
72 
73 int main(){
74     //freopen("in.txt", "r", stdin);
75     while(~scanf("%d", &n)){
76         root = size = 0;
77         int ans = 0;
78         for(int i = 1; i <= n; i++){
79             int num;
80             if(scanf("%d", &num) == EOF) num = 0;
81             if(i == 1){
82                 ans += num;
83                 new_node(root, 0, num);
84                 continue;
85             }
86             if(!insert(num)) continue;
87             int a = get_next(root);
88             int b = get_pre(root);
89             ans += min(a, b);
90         }
91         printf("%d\n", ans);
92     }
93     return 0;
94 }
View Code

 

posted @ 2015-10-02 19:15  astoninfer  阅读(153)  评论(0编辑  收藏  举报