【HNOI 2002 】营业额统计

Description

Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。
Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业 额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了 一种最小波动值来衡量这种情况:
该天的最小波动值=min{ |该天以前某一天的营业额-该天营业额| }。

当最小波动值越大时,就说明营业情况越不稳定。
而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。
第一天的最小波动值为第一天的营业额。

Input

第一行为正整数n(n<=32767),表示该公司从成立一直到现在的天数,接下来的n行每行有一个正整数ai(ai<=1000000),表示第i天公司的营业额。

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

Source

HNOI 2002
排序,STL

思路{

  嗯哼,第一道Splay。(参考jessliu大神的代码)

  左旋,右旋操作要分清!

}

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<queue>
 7 #include<ctime>
 8 #include<cmath>
 9 #include<map>
10 #include<set>
11 #define MAXX 32767
12 #define INF 6666666
13 #define LL long long
14 #define RG register
15 using namespace std;
16 int key[MAXX],ch[MAXX][3],pre[MAXX],n,tot,root;
17 LL ans;
18 inline void make(RG int &x,RG int fa,RG int num){
19   x=++tot,pre[x]=fa,key[x]=num;ch[x][0]=ch[x][1]=0;
20 }
21 inline void Rotate(RG int x,RG int kind){//1 右旋,0左旋
22   RG int y=pre[x];
23   ch[y][!kind]=ch[x][kind];
24   pre[ch[x][kind]]=y;
25   if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;
26   pre[x]=pre[y];pre[y]=x;ch[x][kind]=y;
27 }
28 inline void Splay(RG int x,RG int goal){
29   while(pre[x]!=goal)
30     if(pre[pre[x]]==goal)Rotate(x,ch[pre[x]][0]==x);
31     else {
32       RG int y=pre[x];
33       RG int kind=(ch[pre[y]][0]==y);
34       if(ch[y][kind]==x)Rotate(x,!kind),Rotate(x,kind);
35       //zig-zag or zag-zig
36       else Rotate(y,kind),Rotate(x,kind);
37       //zig-zig or zag-zag
38     }
39   if(goal==0)root=x;
40 }
41 inline bool Insert(RG int x){
42   while(ch[root][key[root]<x]){
43     if(key[root]==x){Splay(root,0);return 0;}
44     root=ch[root][key[root]<x];
45   }make(ch[root][key[root]<x],root,x);
46   Splay(ch[root][key[root]<x],0);return 1;
47 }
48 inline int minmax(RG int x){
49   RG int now=ch[x][0];
50   if(!now)return INF;
51   while(ch[now][1])now=ch[now][1];
52   return key[now];
53 }
54 inline int maxmin(RG int x){
55   RG int now=ch[x][1];
56   if(!now)return INF;
57   while(ch[now][0])now=ch[now][0];
58   return key[now];
59 }
60 int main(){
61   scanf("%d",&n);
62   for(RG int i=1;i<=n;++i){RG int num;
63     if(scanf("%d",&num)==EOF)num=0;
64     if(i==1){
65       ans+=num;
66       make(root,0,num);
67       continue;
68     }
69     if(Insert(num)==0)continue;
70     RG int maxx=maxmin(root);
71     RG int minn=minmax(root);
72     ans+=(LL)min(abs(maxx-num),abs(minn-num));
73   }printf("%lld",ans);
74   return 0;
75 }
原文地址:https://www.cnblogs.com/zzmmm/p/6664548.html