说明
Tiger 最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger 拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。 经济管理学上定义了一种最小波动值来衡量这种情况:记该天以前某一天的营业额为 ,该天营业额为 b,则该天的最小波动值δ=min∣
−b∣,当最小波动值越大时,就说明营业情况越不稳定。而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。 你的任务就是编写一个程序帮助 Tiger 来计算这一个值,第一天的最小波动值为第一天的营业额。
一句话题意
给出一个 n 个数的数列 {
},对于第 i 个元素
,定义
=min∣
−
∣,其中 1≤j<i,
=
。求 ∑
输入格式
第一行为正整数,表示该公司从成立一直到现在的天数; 接下来的 n 行每行有一个整数,表示第 i 天公司的营业额 。
输出格式
仅有一个正整数,即每一天最小波动的和,结果不超过 。
样例
输入数据 1
6
5
1
2
5
4
6
输出数据 1
12
#include<bits/stdc++.h>
using namespace std;
struct S{
int lc,rc,vis,pos,cnt,sze;
}t[500005];int n,m,cnt=0,rt;
void zig(int &k){
int y=t[k].lc;
t[k].lc=t[y].rc;
t[y].rc=k;
t[y].sze=t[k].sze;
t[k].sze=t[t[k].lc].sze+t[t[k].rc].sze+t[k].cnt;
k=y;
}
void zag(int &k){
int y=t[k].rc;
t[k].rc=t[y].lc;
t[y].lc=k;
t[y].sze=t[k].sze;
t[k].sze=t[t[k].lc].sze+t[t[k].rc].sze+t[k].cnt;
k=y;
}
void inse(int &k,int key){
if(!k){
k=++cnt;t[k].vis=key;t[k].pos=rand();
t[k].cnt=t[k].sze=1;t[k].lc=t[k].rc=0;
return ;
}
else ++t[k].sze;
if(t[k].vis==key)++t[k].cnt;
else if(key<t[k].vis){
inse(t[k].lc,key);
if(t[t[k].lc].pos<t[k].pos)zig(k);
}
else {
inse(t[k].rc,key);
if(t[t[k].rc].pos<t[k].pos)zag(k);
}
return ;
}
void del(int &k,int key){
if(t[k].vis==key){
if(t[k].cnt>1)--t[k].cnt,--t[k].sze;
else if(!t[k].lc || !t[k].rc)k=t[k].lc+t[k].rc;
else if(t[t[k].lc].pos<t[t[k].rc].pos)zig(k),del(k,key);
else zag(k),del(k,key);
return ;
}
--t[k].sze;
if(key<t[k].vis)del(t[k].lc,key);
else del(t[k].rc,key);
}
int quepre(int key){
int k=rt,res=-0x3f3f3f3f;
while(k){
if(t[k].vis<=key)res=t[k].vis,k=t[k].rc;
else k=t[k].lc;
}
return res;
}
int quenex(int key){
int k=rt,nex=0x3f3f3f3f;
while(k){
if(t[k].vis>=key)nex=t[k].vis,k=t[k].lc;
else k=t[k].rc;
}
return nex;
}
int main(){
int n;
int op,x,anss,xx,yy;
scanf("%d",&n);
scanf("%d",&anss);
inse(rt,anss);
while(--n){
scanf("%d",&x);
xx=quepre(x),yy=quenex(x);
anss+=min(x-xx,yy-x);
inse(rt,x);
}
printf("%d",anss);
return 0;
}