洛谷P2234 [HNOI2002]营业额统计

题目:https://www.luogu.org/problemnew/show/P2234

题目描述

Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。

Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况:

当最小波动值越大时,就说明营业情况越不稳定。

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

第一天的最小波动值为第一天的营业额。

该天的最小波动值=min{|该天以前某一天的营业额-该天营业额|}。

输入输出格式

输入格式:

 

输入由文件’turnover.in’读入。

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

 

输出格式:

 

输出到文件'tumover.out'。
输出文件仅有一个正整数,即∑每一天的最小波动值。结果小于2^31。

 

输入输出样例

输入样例#1: 复制
6
5
1
2
5
4
6
输出样例#1: 复制
12

说明

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

 

解析:

人生中第一道splay(我还是太弱了)。

参照大佬的磕磕绊绊地写完了。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 using namespace std;
  7 struct node{
  8     int fa;
  9     int ls,rs;
 10     int num;
 11 }a[100010];
 12 int ans;
 13 int n,root;
 14 bool same;
 15 void lrotate(int x){
 16     int y=a[x].fa,z=a[y].fa;
 17     a[y].rs=a[x].ls;
 18     if (a[x].ls) a[a[x].ls].fa=y;
 19     a[x].fa=z;
 20     if (z){
 21         if (a[z].ls==y) a[z].ls=x;
 22         else a[z].rs=x;
 23     }
 24     a[x].ls=y; a[y].fa=x;
 25 }
 26 void rrotate(int x){
 27     int y=a[x].fa,z=a[y].fa;
 28     a[y].ls=a[x].rs;
 29     if (a[x].rs) a[a[x].rs].fa=y;
 30     a[x].fa=z;
 31     if (z){
 32         if (a[z].ls==y) a[z].ls=x;
 33         else a[z].rs=x;
 34     }
 35     a[x].rs=y; a[y].fa=x;
 36 }
 37 void splay(int x){
 38     while (a[x].fa){
 39         int y=a[x].fa,z=a[y].fa;
 40         if (!z){
 41             if (a[y].ls==x) rrotate(x);
 42             else lrotate(x);
 43         }else{
 44             if (a[z].ls==y&&a[y].ls==x){
 45                 rrotate(y);
 46                 rrotate(x);
 47             }
 48             if (a[z].rs==y&&a[y].rs==x){
 49                 lrotate(y);
 50                 lrotate(x);
 51             }
 52             if (a[z].ls==y&&a[y].rs==x){
 53                 lrotate(x);
 54                 rrotate(x);
 55             }
 56             if (a[z].rs==y&&a[y].ls==x){
 57                 rrotate(x);
 58                 lrotate(x);
 59             }
 60         }
 61     }
 62     root=x;
 63 }
 64 void bins(int x,int root){
 65     if (a[x].num==a[root].num){
 66         splay(root);
 67         same=true;
 68         return;
 69     }
 70     if (a[x].num<a[root].num){
 71         if (!a[root].ls){
 72             a[root].ls=x;
 73             a[x].fa=root;
 74         }else{
 75             bins(x,a[root].ls);
 76         }
 77     }else{
 78         if (!a[root].rs){
 79             a[root].rs=x;
 80             a[x].fa=root;
 81         }else{
 82             bins(x,a[root].rs);
 83         }
 84     }
 85 }
 86 int sma(int x){
 87     int p=a[x].ls;
 88     if (!p) return p;
 89     while (a[p].rs) p=a[p].rs;
 90     return p;
 91 }
 92 int bie(int x){
 93     int p=a[x].rs;
 94     if (!p) return p;
 95     while (a[p].ls) p=a[p].ls;
 96     return p;
 97 }
 98 void ins(int x){
 99     same=false;
100     bins(x,root);
101     if (same) return;
102     splay(x);
103     int minx=23333333;
104     int c=sma(x),d=bie(x);
105     if (c) minx=min(minx,abs(a[x].num-a[c].num));
106     if (d) minx=min(minx,abs(a[x].num-a[d].num));
107     ans+=minx;
108 }
109 int main(){
110     scanf("%d",&n);
111     root=1;
112     scanf("%d",&a[1].num);
113     ans+=a[1].num;
114     for (int i=2;i<=n;++i){
115         scanf("%d",&a[i].num);
116         ins(i);
117     }
118     printf("%d",ans);
119     return 0;
120 }
View Code

 

posted @ 2018-02-05 19:13  lonlyn  阅读(210)  评论(2编辑  收藏  举报