1. 程式人生 > >[HNOI2002]營業額統計

[HNOI2002]營業額統計

編寫 可能 memory discuss rotate 這一 out ++ 統計

Time Limit: 5 Sec Memory Limit: 162 MB
Submit: 15956 Solved: 6358
[Submit][Status][Discuss]

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


該題數據bug已修復.----2016.5.15

思路

splay

代碼實現

 1 #include<cstdio>
 2 const int maxn=5e4+10;
 3 int n,size;
 4 int f[maxn],s[maxn][2],d[maxn];
 5 //f儲存父節點編號,s儲存左右子,d儲存該節點的值。
 6 int head,now,up,down,ans;
 7 inline int min_(int x,int y){return x<y?x:y;}
 8 void rotate(int x,int &k){
9 int a=f[x],b=f[a],l,r; 10 l=s[a][0]==x?0:1; 11 r=l^1; 12 if(a==k) k=x; 13 else{ 14 if(s[b][0]==a) s[b][0]=x; 15 else s[b][1]=x; 16 } 17 f[x]=b,f[a]=x,f[s[x][r]]=a; 18 s[a][l]=s[x][r],s[x][r]=a; 19 } 20 void splay(int x,int &k){ 21 int a,b; 22 while(x!=k){ 23 a=f[x],b=f[a]; 24 if(a!=k){ 25 if(s[a][0]==x^s[b][0]==a) rotate(x,k); 26 else rotate(a,k); 27 } 28 rotate(x,k); 29 } 30 } 31 void ins(int &k,int x,int fa){ 32 if(!k){ 33 size++,k=size; 34 d[k]=x,f[k]=fa; 35 splay(k,head); 36 return; 37 } 38 if(x<d[k]) ins(s[k][0],x,k); 39 else ins(s[k][1],x,k); 40 } 41 void ask_down(int k,int x){ 42 if(k==0) return; 43 if(d[k]<=x) down=d[k],ask_down(s[k][1],x); 44 else ask_down(s[k][0],x); 45 } 46 void ask_up(int k,int x){ 47 if(k==0) return; 48 if(d[k]>=x) up=d[k],ask_up(s[k][0],x); 49 else ask_up(s[k][1],x); 50 } 51 int main(){ 52 scanf("%d",&n); 53 for(int i=1;i<=n;i++){ 54 scanf("%d",&now); 55 up=1e9,down=-1e9; 56 ask_down(head,now); 57 ask_up(head,now); 58 if(i!=1) ans+=min_(up-now,now-down); 59 else ans+=now; 60 ins(head,now,0); 61 } 62 printf("%d\n",ans); 63 return 0; 64 }

[HNOI2002]營業額統計