bzoj1588:[Hnoi2002]营业额统计

Description

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

Input

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

Output

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

Sample Input

6
5
1
2
5
4
6

Sample Output

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

这个就是个裸的splay tree啊

 

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 using namespace std;
 5 int v[50001],s[50001][2],n,m,f[50001],now,ans;
 6 int get(int x)
 7 {
 8     return s[f[x]][1]==x;
 9 }
10 int get_min(int now)
11 {
12     while(s[now][1])now=s[now][1];
13     return now;
14 }
15 int get_max(int now)
16 {
17     while(s[now][0])now=s[now][0];
18     return now;
19 }
20  
21 void move(int now)
22 {
23     int fa=f[now],cnt=get(now),faa=f[fa];
24     s[fa][cnt]=s[now][cnt^1];
25     f[s[now][cnt^1]]=fa;
26     s[now][cnt^1]=fa;
27     if(faa)s[faa][get(fa)]=now;
28     f[now]=faa;
29     f[fa]=now;
30 }
31  
32 void splay(int x)
33 {
34     for(int fa;(fa=f[x]);move(x))
35         if(f[fa])move((get(x)==get(fa)?fa:x));
36 }
37  
38 void ins(int m)
39 {
40     v[++now]=m;
41     int rt=now-1;
42     while(1)
43     {
44         if(m<=v[rt])
45         {
46             if(!s[rt][0])
47             {
48                 s[rt][0]=now;
49                 f[now]=rt;
50                 break;
51             }
52             rt=s[rt][0];
53         }
54         else
55         {
56             if(!s[rt][1])
57             {
58                 s[rt][1]=now;
59                 f[now]=rt;
60                 break;
61             }
62             rt=s[rt][1];
63         }
64     }
65     splay(now);
66 }
67  
68 int main()
69 {
70     scanf("%d",&n);
71     scanf("%d",&v[++now]);ans=v[now];
72     for(int i=2;i<=n;i++)
73     {
74         scanf("%d",&m);ins(m);
75         int t1=get_max(s[now][1]),t2=get_min(s[now][0]);
76         t1=t1?v[t1]:1e9;t2=t2?v[t2]:1e9;
77         ans+=min(abs(t2-m),abs(t1-m));
78     }
79     printf("%d\n",ans);
80 }

 

posted @ 2018-08-08 11:05  蒟蒻--lichenxi  阅读(136)  评论(0编辑  收藏  举报