1588: [HNOI2002]营业额统计

Time Limit: 5 Sec Memory Limit: 162 MB

Description

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

Input

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

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旋转,查找前驱和后继.
数据可能有负数.
cogs上卡读入优化orz.
*/
#include<iostream>
#include<cstdio>
#define MAXN 50001
#define INF 1e9
using namespace std;
int n,tree[MAXN][2],t1,t2,root,fa[MAXN],num[MAXN],size,ans,x1,x2;
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void rotate(int x,int &k)
{
int y=fa[x],z=fa[y],l,r;
if(tree[y][0]==x) l=0;else l=1;r=l^1;
if(y==k) k=x;
else {
if(tree[z][0]==y) tree[z][0]=x;//拆.
else tree[z][1]=x;
}
fa[x]=z,fa[y]=x;fa[tree[x][r]]=y;
tree[y][l]=tree[x][r];tree[x][r]=y;
return ;
}
void splay(int x,int &k)
{
int y,z;
while(x!=k)
{
y=fa[x],z=fa[y];
if(y!=k)
{
if((tree[y][0]==x)^(tree[z][0]==y)) rotate(x,k);//共线旋转孙子.
else rotate(y,k);//不共线旋转儿子.
}
rotate(x,k);
}
return ;
}
void add(int &k,int x,int f)//加入元素.
{
if(!k){size++;k=size;num[k]=x;fa[k]=f;splay(k,root);return;}
if(x<num[k]) add(tree[k][0],x,k);//维护二叉树性质.
else add(tree[k][1],x,k);
return ;
}
void before(int k,int x)//查找前驱.
{
if(!k) return ;
if(num[k]<=x){t1=num[k];x1=k;before(tree[k][1],x);}
else before(tree[k][0],x);
return ;
}
void after(int k,int x)//查找后继.
{
if(!k) return ;
if(num[k]>=x){t2=num[k];x2=k;after(tree[k][0],x);}
else after(tree[k][1],x);
return ;
}
int main()
{
freopen("turnover.in","r",stdin);
freopen("turnover.out","w",stdout);
int x;
n=read();
x=read(),add(root,x,0),ans=x;
for(int i=2;i<=n;i++)
{
x=read();//scanf("%d",&x);
x1=x2=0;
before(root,x);
after(root,x);
if(!x1) ans+=t2-x;
else if(!x2) ans+=x-t1;
else ans+=min(x-t1,t2-x);
add(root,x,0);
}
printf("%d",ans);
return 0;
}

最新文章

  1. WPF进度条系列②旋转小圆圈
  2. 电信级的RSA加密后的密码的破解方法
  3. docker本地私有仓库的创建,及https错误修正
  4. You Only Live Once
  5. Keynote of Python III
  6. eigen主页
  7. linux之SQL语句简明教程---WHERE
  8. L10 PUtty+SSH 访问vncviewer
  9. kill-mysql-sleep.sh
  10. Spring 基于注解的AOP实现
  11. 前端加密传输 crypto-js AES 加密和解密
  12. React(二)组件
  13. 监听 input上传文件, 获取文件名称,
  14. JavaEE-Servlet的部署和配置
  15. $.fn.extend() 问:我来这个世上到底是干嘛的?
  16. python六十三课——高阶函数之sorted
  17. Atcode ABC105-C:Base -2 Number
  18. elasticsearch配置详解
  19. django的cache
  20. Java多态 父类引用指向子类对象

热门文章

  1. ASP.NET Core分布式项目-3.oauth2与open id connect 对比
  2. Jmeter5.1——聚合报告参数分析
  3. AngularJS入门教程之与服务器(Ajax)交互操作示例
  4. S2-033、S2-037
  5. Mysql基础学习_Windows版(一)
  6. bootstrap 分页行数选择按钮失效
  7. MySQL数据库的启动与停止
  8. linux设置密钥登录(只允许密钥登录)
  9. 线段树lazy模板 luogu3372
  10. ubuntu---记录.简单一句话安装tf