洛谷P2234 [HNOI2002] 營業額統計 [splay]
阿新 • • 發佈:2018-08-17
region orange img reg esp 突變 pla != microsoft
題目傳送門
營業額統計
題目描述
Tiger最近被公司升任為營業部經理,他上任後接受公司交給的第一項任務便是統計並分析公司成立以來的營業情況。
Tiger拿出了公司的賬本,賬本上記錄了公司成立以來每天的營業額。分析營業情況是一項相當復雜的工作。由於節假日,大減價或者是其他情況的時候,營業額會出現一定的波動,當然一定的波動是能夠接受的,但是在某些時候營業額突變得很高或是很低,這就證明公司此時的經營狀況出現了問題。經濟管理學上定義了一種最小波動值來衡量這種情況:
當最小波動值越大時,就說明營業情況越不穩定。
而分析整個公司的從成立到現在營業情況是否穩定,只需要把每一天的最小波動值加起來就可以了。你的任務就是編寫一個程序幫助Tiger來計算這一個值。
第一天的最小波動值為第一天的營業額。
該天的最小波動值=min{|該天以前某一天的營業額-該天營業額|}。
輸入輸出格式
輸入格式:
輸入由文件’turnover.in’讀入。
第一行為正整數n(n<=32767) ,表示該公司從成立一直到現在的天數,接下來的n行每行有一個整數ai(|ai|<=1000000) ,表示第i天公司的營業額,可能存在負數。
輸出格式:
輸入輸出樣例
輸入樣例#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$,速度還說的過去。
Code:
//It is made by HolseLee on 17th Aug 2018 //Luogu.org P2234 #include<bits/stdc++.h> #define Max(a,b) (a)>(b)?(a):(b) #define Min(a,b) (a)<(b)?(a):(b) #defineAbs(a) (a)>0?(a):-(a) using namespace std; const int inf=1e9; const int N=1e5+7; int n,tot,root,ans; struct Node{ int val,num,ch[2],fa; void add(int x,int f) { ch[0]=ch[1]=0,num=1; fa=f,val=x; } }t[N]; inline int read() { char ch=getchar();int num=0;bool flag=false; while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)flag=true;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){num=num*10+ch-‘0‘;ch=getchar();} return flag?-num:num; } inline void rotate(int x) { int y=t[x].fa,z=t[y].fa; int k=(t[y].ch[1]==x); t[z].ch[t[z].ch[1]==y]=x; t[x].fa=z; t[t[x].ch[k^1]].fa=y; t[y].ch[k]=t[x].ch[k^1]; t[x].ch[k^1]=y; t[y].fa=x; } inline void splay(int x,int tar) { int y,z; while(t[x].fa!=tar){ y=t[x].fa,z=t[y].fa; if(z!=tar){ (t[z].ch[1]==y)^(t[y].ch[1]==x)?rotate(x):rotate(y); } rotate(x); } if(tar==0)root=x; } inline void insert(int x) { int now=root,fa=0; while(now){ if(t[now].val==x)break; fa=now,now=t[now].ch[x>t[now].val]; } if(!now){ now=++tot;t[now].add(x,fa); if(fa)t[fa].ch[x>t[fa].val]=now; }else{ t[now].num++; } splay(now,0); } inline int lower(int x) { int ret=-inf,now=root; while(now){ if(t[now].val==x){ return x; }else if(t[now].val<x){ ret=Max(ret,t[now].val); now=t[now].ch[1]; }else if(t[now].val>x){ now=t[now].ch[0]; } } return ret; } inline int upper(int x) { int ret=inf,now=root; while(now){ if(t[now].val==x){ return x; }else if(t[now].val>x){ ret=Min(ret,t[now].val); now=t[now].ch[0]; }else if(t[now].val<x){ now=t[now].ch[1]; } } return ret; } int main() { n=read(); int x,ka,lu; for(int i=1;i<=n;++i){ x=read(); if(i==1){ ans+=x; }else{ ka=Abs(x-lower(x)); lu=Abs(x-upper(x)); ans+=Min(lu,ka); } insert(x); } printf("%d\n",ans); return 0; }
洛谷P2234 [HNOI2002] 營業額統計 [splay]