[HNOI 2002]营业额统计

Description

营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。  输入输出要求

Input

第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数(有可能有负数) ,表示第i
天公司的营业额。
天数n<=32767,
每天的营业额ai <= 1,000,000。
最后结果T<=2^31

Output

输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。

Sample Input

6
5
1
2
5
4
6

Sample Output

12

HINT 

结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12

题解

强转数组版第一发。裸的平衡树找前驱后继。

 1 //It is made by Awson on 2017.11.15
 2 #include <set>
 3 #include <map>
 4 #include <cmath>
 5 #include <ctime>
 6 #include <queue>
 7 #include <stack>
 8 #include <cstdio>
 9 #include <string>
10 #include <vector>
11 #include <cstdlib>
12 #include <cstring>
13 #include <iostream>
14 #include <algorithm>
15 #define LL long long
16 #define Max(a, b) ((a) > (b) ? (a) : (b))
17 #define Min(a, b) ((a) < (b) ? (a) : (b))
18 using namespace std;
19 const int N = 32767;
20 const int INF = ~0u>>1;
21 
22 int n, a, ans;
23 struct Splay_tree {
24   int pre[N+5], ch[N+5][2], key[N+5], root, pos;
25   void newnode(int &o, int keyy, int fa) {
26     o = ++pos;
27     key[o] = keyy, pre[o] = fa;
28     ch[o][0] = ch[o][1] = 0;
29   }
30   void rotate(int o, int kind) {
31     int p = pre[o];
32     ch[p][!kind] = ch[o][kind], pre[ch[o][kind]] = p;
33     ch[pre[p]][ch[pre[p]][1] == p] = o; pre[o] = pre[p];
34     ch[o][kind] = p, pre[p] = o;
35   }
36   void splay(int o, int goal) {
37     while (pre[o] != goal) {
38       if (pre[pre[o]] == goal) rotate(o, ch[pre[o]][0] == o);
39       else {
40     int p = pre[o], kind = ch[pre[p]][0] == p;
41     if (ch[p][kind] == o) rotate(o, !kind), rotate(o, kind);
42     else rotate(p, kind), rotate(o, kind);
43       }
44     }
45     if (goal == 0) root = o;
46   }
47   bool insert(int &o, int keyy, int fa) {
48     if (!o) {
49       newnode(o, keyy, fa); splay(o, 0);
50       return 0;
51     }
52     if (key[o] == keyy) {
53       splay(o, 0); return 1;
54     }
55     return insert(ch[o][key[o] < keyy], keyy, o);
56   }
57   int get_nex(int o) {
58     if (!ch[o][1]) return INF;
59     o = ch[o][1];
60     while (ch[o][0]) o = ch[o][0];
61     return key[o];
62   }
63   int get_las(int o) {
64     if (!ch[o][0]) return INF;
65     o = ch[o][0];
66     while (ch[o][1]) o = ch[o][1];
67     return key[o];
68   }
69 }S;
70 
71 void work() {
72   scanf("%d", &n);
73   scanf("%d", &a); S.insert(S.root, a, 0);
74   ans = a;
75   for (int i = 1; i < n; i++) {
76     scanf("%d", &a);
77     bool t = S.insert(S.root, a, 0);
78     if (!t) {
79       int tmp = INF, b = S.get_nex(S.root);
80       if (b != INF) tmp = Min(tmp, b-a);
81       b = S.get_las(S.root);
82       if (b != INF) tmp = Min(tmp, a-b);
83       ans += tmp;
84     }
85   }
86   printf("%d\n", ans);
87 }
88 int main() {
89   work();
90   return 0;
91 }

 

转载于:https://www.cnblogs.com/NaVi-Awson/p/7851129.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值