1588: [HNOI2002]营业额统计
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 10070 Solved: 3462
[ Submit][ Status][ Discuss]
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
此题数据有问题,详见讨论版http://www.lydsy.com/JudgeOnline/wttl/wttl.php?pid=1588
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
const int maxn=50005;
const int inf=1e9;
const int oo=1e9;
struct slaytree
{
int son[maxn][2],pre[maxn],val[maxn];
int rt,Size;
inline void Rotate(int x, int c)
{
int y=pre[x];
son[y][!c]=son[x][c];
pre[son[x][c]]=y;
pre[x]=pre[y];
if(pre[x]) son[pre[y]][son[pre[y]][1]==y]=x;
son[x][c]=y;
pre[y]=x;
}
inline void Splay(int x, int goal)
{
while(pre[x]!=goal)
{
if(pre[pre[x]]==goal)
{
if(son[pre[x]][0]==x)
Rotate(x,1);
else
Rotate(x,0);
}
else
{
int y=pre[x], z=pre[y];
if(son[z][0]==y)
{
if(son[y][0]==x)
Rotate(y,1), Rotate(x,1);
else
Rotate(x,0), Rotate(x,1);
}
else
{
if(son[y][1]==x)
Rotate(y,0), Rotate(x,0);
else
Rotate(x,1), Rotate(x,0);
}
}
}
if(goal==0) rt=x;
}
inline void Newnode(int y,int &x,int a)
{
x=++Size;
pre[x]=y;
val[x]=a;
son[x][0]=son[x][1]=0;
}
inline void init()
{
Size=0;
Newnode(0,rt,-inf);
Newnode(rt,son[rt][1],inf);
}
inline void Insert(int a)
{
int x=rt;
while(son[x][val[x]<a]) x=son[x][val[x]<a];
Newnode(x,son[x][val[x]<a],a);
Splay(Size,0);
}
inline int fx_min(int a)//找比a大的最小值
{
int x=rt,minn=inf;
while(x)
{
if(val[x]==a) return a;
if(val[x]>a) minn=min(minn,val[x]);
if(val[x]>a) x=son[x][0];
else x=son[x][1];
}
return minn;
}
inline int fx_max(int a)//找比a小的最大值
{
int x=rt,maxx=-inf;
while(x)
{
if(val[x]==a) return a;
if(val[x]<a) maxx=max(maxx,val[x]);
if(val[x]<a) x=son[x][1];
else x=son[x][0];
}
return maxx;
}
}spt;
int main()
{
int n,a;
scanf("%d%d",&n,&a);
int ans=a;
spt.init();
spt.Insert(a);
while(--n)
{
if(scanf("%d",&a)==-1) a=0;//数据有问题 不满n个数 后面数据要全为0才能A
//scanf("%d",&a);
ans+=min(fabs(a-spt.fx_min(a)),fabs(spt.fx_max(a)-a));
spt.Insert(a);
}
cout<<ans<<endl;
}