[HNOI2002]营业额统计

Description

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

Input

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

Output

输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。
 
 
 
伸展树splay解法,杀千刀的八中OJ数据有问题......
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string.h>
  5 #include<cstdlib>
  6 #include<cmath>
  7 #include<fstream>
  8 #define N 40000
  9 #define Max 100000000
 10 using namespace std;
 11 
 12 int n,root,tot=0,key[N],pre[N],ch[N][2];
 13 long long ans=0;
 14 
 15 void Newnode(int &x,int father,int k){
 16     x=++tot;pre[x]=father;key[x]=k;
 17     ch[x][0]=ch[x][1]=0;return ;
 18     }
 19 
 20 void Rotate(int x,int kind){
 21     int y=pre[x];
 22     ch[y][!kind]=ch[x][kind];
 23     pre[ch[x][kind]]=y;
 24     
 25     if(pre[y])
 26       ch[pre[y]][ch[pre[y]][1]==y]=x;
 27     pre[x]=pre[y];
 28     pre[y]=x;
 29     ch[x][kind]=y;
 30     return ;
 31     }
 32 
 33 void Splay(int x,int goal){
 34     while(pre[x]!=goal)
 35     {
 36         int y=pre[x];
 37         if(pre[y]==goal) Rotate(x,ch[y][0]==x);
 38         else
 39         {
 40             int z=pre[y];
 41             int kind=ch[z][0]==y;
 42             if(ch[y][!kind]==x)
 43             {Rotate(y,kind);Rotate(x,kind);}
 44             else {Rotate(x,!kind);Rotate(x,kind);}
 45             }
 46         }
 47     root=x;return ;
 48     }
 49 
 50 int Insert(int m){
 51     int x=root;
 52     while(ch[x][key[x]<m])
 53     {
 54         if(key[ch[x][key[x]<m]]==m) return 0;
 55         x=ch[x][key[x]<m];
 56         }
 57     Newnode(ch[x][key[x]<m],x,m);
 58     Splay(ch[x][key[x]<m],0);
 59     return 1;
 60     
 61     }
 62 
 63 int Pre(int x){
 64     if(ch[x][0]==0) return Max;
 65     int y=ch[x][0];
 66     while(ch[y][1]) y=ch[y][1];
 67     return key[y];
 68     }
 69 
 70 int Next(int x){
 71     if(ch[x][1]==0) return Max;
 72     int y=ch[x][1];
 73     while(ch[y][0]) y=ch[y][0];
 74     return key[y]; 
 75     }
 76 
 77 int main()
 78 {
 79     while(cin>>n)
 80     {
 81         for(int i=1;i<=n;++i)
 82         {
 83             int m=0;
 84             cin>>m;
 85             if(i==1)
 86             {
 87                 ans+=m;
 88                 Newnode(root,0,m);
 89                 continue;
 90                 }    
 91             if(Insert(m)==0) continue;
 92             int a=Pre(root);
 93             int b=Next(root);
 94             ans+=min(abs(m-a),abs(m-b));
 95             }
 96 
 97         }
 98     cout<<ans<<endl;
 99 
100     return 0;
101     }
 
学习新东西对拍想必是极好的。
原文地址:https://www.cnblogs.com/noip/p/3112002.html