题目
题目描述
Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。
Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况:
当最小波动值越大时,就说明营业情况越不稳定。
而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。
第一天的最小波动值为第一天的营业额。
该天的最小波动值=min{|该天以前某一天的营业额-该天营业额|}。
分析
splay的模板题。
利用二分查找树的性质即可找到最接近的两个数。
如果是最大或最小特殊处理一下即可
code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<string>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
const int N=100005;
const int inf=0X7fffffff;
struct tree{
int l,r; int fa,k; int s;
}t[N];
int n;
int delta,ans;
int root,tot;
void rttl(int x)
{
int y=t[x].r;
if (x==root) root=y;
t[x].r=t[y].l; t[t[y].l].fa=x; t[y].l=x; t[y].fa=t[x].fa;
if (x==t[t[x].fa].l) t[t[x].fa].l=y;
else t[t[x].fa].r=y;
t[x].fa=y; t[x].s=t[t[x].l].s+t[t[x].r].s+1; t[y].s=t[t[y].l].s+t[t[y].r].s+1;
}
void rttr(int x)
{
int y=t[x].l;
if (x==root) root=y;
t[x].l=t[y].r; t[t[y].r].fa=x; t[y].r=x; t[y].fa=t[x].fa;
if (x==t[t[x].fa].l) t[t[x].fa].l=y;
else t[t[x].fa].r=y;
t[x].fa=y; t[x].s=t[t[x].l].s+t[t[x].r].s+1; t[y].s=t[t[y].l].s+t[t[y].r].s+1;
}
void splay(int x)
{
while (x!=root)
{
int f=t[x].fa;
if (f==root)
if (x==t[f].l) rttr(f);
else rttl(f);
else
{
int p=t[f].fa;
if (x==t[f].l)
{
if (f==t[p].l)
{rttr(p); rttr(f);}
else
{rttr(f); rttl(p);}
}
else
{
if (f==t[p].l)
{rttl(f); rttr(p);}
else
{rttl(p); rttl(f);}
}
}
}
}
void insert(int k)
{
if (!root)
{
root=++tot; t[tot].s=1; t[tot].k=k;
return;
}
int x=root,y;
while (x)
{
y=x; t[x].s++;
if (k<t[x].k) x=t[x].l;
else x=t[x].r;
}
t[++tot].s=1; t[tot].k=k; t[tot].fa=y;
if (k<t[y].k) t[y].l=tot;
else t[y].r=tot;
splay(tot);
}
int f1,f2;
int mi(int xx)
{
if (t[xx].s==0)
{
f1=0;
}
int x=xx;
while (t[x].r)
{
x=t[x].r;
}
return t[x].k;
}
int ma(int xx)
{
if (t[xx].s==0)
{
f2=0;
}
int x=xx;
while (t[x].l)
{
x=t[x].l;
}
return t[x].k;
}
int find(int xx)
{
int x=root;
while (t[t[x].l].s+1!=xx)
{
if (t[t[x].l].s+1<xx)
{
xx-=t[t[x].l].s+1; x=t[x].r;
}
else
{
x=t[x].l;
}
}
splay(x);
return t[x].k;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
insert(x);
f1=1; f2=1;
if (i==1) ans=x;
else
{
int k1=mi(t[root].l);
int k2=ma(t[root].r);
if (f1==0) ans+=k2-x;
else if (f2==0) ans+=x-k1;
else ans+=min(x-k1,k2-x);
}
}
printf("%d\n",ans);
}