题目描述
Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。
Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况:
当最小波动值越大时,就说明营业情况越不稳定。
而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。
第一天的最小波动值为第一天的营业额。
该天的最小波动值=min{|该天以前某一天的营业额-该天营业额|}。
输入输出格式
输入格式:
输入由文件’turnover.in’读入。
第一行为正整数n(n<=32767) ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数ai(|ai|<=1000000) ,表示第i天公司的营业额,可能存在负数。
输出格式:
一行仅一个数表示∑最小波动值
输入输出样例
输入样例#
6
5
1
2
5
4
6
输出样例
12
分析
因为最小波动值的定义,我们不难看出是求一个最近似a的数,很容易知道是写求前驱后继
然后学了Splay打来练练(结果忘记调边界爆掉)
#include <iostream>
#include <cstdio>
#include <cmath>
#define rep(i,a,b) for (i=a;i<=b;i++)
using namespace std;
struct node
{
int c[2],f;
int key,size,cnt;
}t[50001];
int cnt,rt;
void CLEAR(int x)
{
t[x].c[0]=t[x].c[1]=t[x].f=t[x].key=t[x].size=t[x].cnt=0;
}
bool GET(int x)
{
return x==t[t[x].f].c[1];
}
void PUSHUP(int x)
{
if (x)
{
t[x].size=t[x].cnt;
if (t[x].c[0]) t[x].size+=t[t[x].c[0]].size;
if (t[x].c[1]) t[x].size+=t[t[x].c[1]].size;
}
}
void ROTATE(int x)
{
int f=t[x].f,gf=t[f].f,lr=GET(x);
t[f].c[lr]=t[x].c[lr^1];t[t[f].c[lr]].f=f;
t[x].c[lr^1]=f;t[f].f=x;
t[x].f=gf;
if (gf) t[gf].c[f==t[gf].c[1]]=x;
PUSHUP(f);PUSHUP(x);
}
void SPLAY(int x)
{
for (int f;f=t[x].f;ROTATE(x))
if (t[f].f)
ROTATE((GET(x)==GET(f))?f:x);
rt=x;
}
void INSERT(int key)
{
if (!rt)
{
cnt++;rt=cnt;
t[rt].key=key;
t[rt].cnt=t[rt].size=1;
t[rt].c[0]=t[rt].c[1]=0;
return;
}
int x=rt,f=0;
while (1)
{
if (t[x].key==key)
{
t[x].cnt++;
PUSHUP(x);PUSHUP(f);
SPLAY(x);
return;
}
f=x;x=t[x].c[key>t[x].key];
if (!x)
{
cnt++;
t[cnt].key=key;
t[cnt].cnt=t[cnt].size=1;
t[cnt].c[0]=t[cnt].c[1]=0;
t[f].c[key>t[f].key]=cnt;t[cnt].f=f;
PUSHUP(f);SPLAY(cnt);
return;
}
}
}
int GET_PRE()
{
int x=t[rt].c[0];
if (!x) return x;
while (t[x].c[1]) x=t[x].c[1];
return x;
}
int GET_NEXT()
{
int x=t[rt].c[1];
if (!x) return x;
while (t[x].c[0]) x=t[x].c[0];
return x;
}
int main()
{
int n,i,a,ans=0;
scanf("%d",&n);
t[0].key=2147483647;
rep(i,1,n)
{
scanf("%d",&a);
INSERT(a);
if (i==1) ans+=a;
else if (t[rt].cnt==1) ans+=min(abs(t[GET_PRE()].key-a),abs(t[GET_NEXT()].key-a));
}
printf("%d",ans);
}