#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch))
{
ans = ans * 10 + ch - '0'; ch = getchar();
}
if(last == '-') ans = -ans;
return ans;
}
int n, root = 0; //n种操作;root记录根节点是谁(因为进行某一操作后,根节点可能改变,所以要随时记录)
int cnt = 0, lson[maxn], rson[maxn]; //cnt:节点总数(即每一个节点的编号);lson[now],rson[now]:节点now的左右孩子
int val[maxn], ran[maxn], size[maxn], Cnt[maxn];//val[now]:节点now的权值;ran[now]:随机出来的优先级;size[now]:子树大小;
//Cnt[now]记录和val[now]相同的节点多少个(用来处理数字重复)
void update(int now)
{
if(!now) return;
size[now] = size[lson[now]] + size[rson[now]] + Cnt[now];
}
void right_rotate(int& Q)
{
int P = lson[Q];
lson[Q] = rson[P]; //这个和下面那句不能反
rson[P] = Q;
update(Q); update(P);
Q = P;
}
void left_rotate(int& Q)
{
int P = rson[Q];
rson[Q] = lson[P];
lson[P] = Q;
update(Q); update(P);
Q = P;
}
void insert(int& now, int v)//插入v
{
if(!now) //找到要插入的叶节点了
{
now = ++cnt; //新建节点
val[now] = v;
size[now] = Cnt[now] = 1;
ran[now] = rand(); //随机优先级
return;
}
if(val[now] == v) Cnt[now]++; //若树中已经有了该数,就直接Cnt[]++了
else if(val[now] > v) //说明在左子树
{
insert(lson[now], v); //递归寻找
if(ran[lson[now]] < ran[now]) right_rotate(now);
//这一步放在了递归后面,说明此时节点已经插入好了(而且只是修改了左子树),那就判断并通过旋转维护堆
}
else
{
insert(rson[now], v);
if(ran[rson[now]] < ran[now]) left_rotate(now);
}
update(now);
}
void del(int& now, int v)//删除v
{
if(!now) return;
if(val[now] == v) //找到了该数
{
if(Cnt[now] > 1) //有重复
{
Cnt[now]--;
update(now); return;
}
else if(lson[now] && rson[now]) //并没有旋转到根节点
{
left_rotate(now); //只要选任意一棵子树旋转就行
del(lson[now], v); //这两句等价于right_rotate(now); del(rson[now], v);
}
else //代表只剩一个孩子了,那么就直接用他的孩子代替他,相当于把他删除
{
now = lson[now] | rson[now]; //等价于now = lson[now] ? lson[now] : rson[now]
update(now); return;
}
}
else if(val[now] > v) del(lson[now], v); //没找到就接着找
else del(rson[now], v);
update(now);
}
int Find_id(int now, int v)//查询id排名
{
if(!now) return 0;
if(val[now] == v) return size[lson[now]] + 1; //别忘加上自己
if(val[now] > v) return Find_id(lson[now], v);
else return Find_id(rson[now], v) + size[lson[now]] + Cnt[now];
}
int Find_num(int now, int id)//查询排名为id的数
{
if(!now) return INF;
if(size[lson[now]] >= id) return Find_num(lson[now], id); //在左子树
else if(id <= size[lson[now]] + Cnt[now]) return val[now]; //在左子树和自己,但因为左子树的已经走上面的语句了,就指自己
else return Find_num(rson[now], id - size[lson[now]] - Cnt[now]); //右子树,别忘减去(跟线段树找第k小挺像)
}
int Pre(int now, int v)//小于等于
{
if(!now) return -INF;
if(val[now] <= v) return max(val[now], Pre(rson[now], v));//前驱在右子树或是当前节点
else return Pre(lson[now], v);
}
int Nex(int now, int v)//大于等于
{
if(!now) return INF;
if(val[now] >= v) return min(val[now], Nex(lson[now], v));//去掉前面的等号就变成大于了
else return Nex(rson[now], v);
}
int main()
{
n = read();
int x=read(),sum=x;
insert(root,x);
while(--n)
{
x=read();
sum+=min(x-Pre(root,x),Nex(root,x)-x);
//cout<<Pre(root,x)<<endl;
insert(root,x);
//int d = read(), x = read();
}
printf("%d\n",sum);
return 0;
}