1588: [HNOI2002]营业额统计
Time Limit: 5 Sec Memory Limit: 162 MB
Submit: 13027 Solved: 4772
[Submit][Status][Discuss]
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真的好难写,写了好几遍也不对,最后只能写一个稍微简单的splay树了。试过结构体,也试过这样的写法,觉得这个好些,就这个了!
插入的时候,如果已经存在就不需要再次插入,就可以省一些时间了。
【代码】
/**************************************************************
Problem: 1588
User: sdfzwxl
Language: C++
Result: Accepted
Time:1792 ms
Memory:2836 kb
****************************************************************/
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn=100010;
int c[maxn][2],cnt,flag=0,v[maxn],f[maxn],n,t1,t2,rt,x,ans=0;
inline int min(int a,int b)
{return a>b?b:a;}
inline void rot(int x,int &k)
{
int y=f[x],z=f[y],l,r;
if (c[y][0]==x) l=0; else l=1; r=l^1;
if (y==k) k=x;
else{if (c[z][0]==y) c[z][0]=x;else c[z][1]=x;}
f[x]=z;f[y]=x;f[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;
}
inline void splay(int x,int &k)
{
int y,z;
while (x!=k)
{
y=f[x];z=f[y];
if (y!=k)
{
if ((c[y][0]==x)^(c[z][0]==y)) rot(x,k);
else rot(y,k);
}
rot(x,k);
}
}
inline void ins(int &k,int x,int fa)
{
if (!k){k=++cnt;v[k]=x;f[k]=fa;splay(k,rt);return;}
if (x<v[k]) ins(c[k][0],x,k);
else if (x>v[k]) ins(c[k][1],x,k);
}
inline void qp(int k,int x)
{
if (!k) return;
if (v[k]<=x){t1=v[k];qp(c[k][1],x);}
else qp(c[k][0],x);
}
inline void qs(int k,int x)
{
if (!k) return;
if (v[k]>=x){t2=v[k];qs(c[k][0],x);}
else qs(c[k][1],x);
}
int main()
{
scanf("%d",&n);
while (n--)
{
t1=-0x3f3f3f3f; t2=0x3f3f3f3f;
scanf("%d",&x);
if (!flag) ans+=x,flag=1;
else qp(rt,x),qs(rt,x),ans+=min(x-t1,t2-x);
ins(rt,x,0);
}
printf("%d\n",ans);
}