BZOJ1588 HNOI2002 营业额统计 [Splay入门题]
Posted SilverNebula
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1588 HNOI2002 营业额统计 [Splay入门题]相关的知识,希望对你有一定的参考价值。
[HNOI2002]营业额统计
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 4128 Solved: 1305
Description
营业额统计
Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。
Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业
额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了
一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。
而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。
第一天的最小波动值为第一天的营业额。 ? 输入输出要求
Input
第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个正整数 ,表示第i天公司的营业额。
Output
输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。
Sample Input
6
5
1
2
5
4
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
splay
看着就晕,姑且半抄着代码写了下来,以后慢慢刷熟练度好了
1 /**/ 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<algorithm> 7 using namespace std; 8 int INF=100000000; 9 const int mxn=120000; 10 int v[mxn],ch[mxn][2],fa[mxn],root=0,cnt=0; 11 int t1,t2; 12 int n; 13 void rotate(int x,int &k){ 14 int y=fa[x],z=fa[y]; 15 int l,r; 16 if(ch[y][0]==x) l=0; else l=1; 17 r=l^1; 18 if(y==k)k=x; 19 else{ 20 if(ch[z][0]==y) ch[z][0]=x; 21 else ch[z][1]=x; 22 } 23 fa[x]=z;fa[y]=x;fa[ch[x][r]]=y; 24 ch[y][l]=ch[x][r]; 25 ch[x][r]=y; 26 } 27 void splay(int x,int &k){ 28 int y,z; 29 while(x!=k){ 30 y=fa[x];z=fa[y]; 31 if(y!=k){ 32 if((ch[y][0]==x)^(ch[z][0]==y))rotate(x,k); 33 else rotate(y,k); 34 } 35 rotate(x,k); 36 } 37 return; 38 } 39 void insert(int &k,int val,int father){ 40 if(!k){ 41 k=++cnt; 42 v[k]=val; 43 fa[k]=father; 44 splay(k,root); 45 return; 46 } 47 if(val<v[k]) insert(ch[k][0],val,k); 48 else if(val>v[k]) insert(ch[k][1],val,k); 49 } 50 void ask_1(int k,int x){//求前驱 51 if(!k)return; 52 if(x>=v[k]){ 53 t1=v[k]; 54 ask_1(ch[k][1],x); 55 }else ask_1(ch[k][0],x); 56 return; 57 } 58 void ask_2(int k,int x){//求前驱 59 if(!k)return; 60 if(x<=v[k]){ 61 t2=v[k]; 62 ask_2(ch[k][0],x); 63 }else ask_2(ch[k][1],x); 64 return; 65 } 66 int main(){ 67 scanf("%d",&n); 68 int i,j,x; 69 bool first=1; 70 int ans=0; 71 for(i=1;i<=n;i++){ 72 scanf("%d",&x); 73 t1=-INF; 74 t2=INF; 75 if(first){ 76 first=0; 77 ans+=x; 78 } 79 else { 80 ask_1(root,x); 81 ask_2(root,x); 82 ans+=min(x-t1,t2-x); 83 } 84 insert(root,x,0); 85 } 86 printf("%d\n",ans); 87 return 0; 88 }
以上是关于BZOJ1588 HNOI2002 营业额统计 [Splay入门题]的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 1588: [HNOI2002]营业额统计 treap