analysis
splay裸题对吧
只需要一直插入,然后不断的找前驱和后继,然后不断的累加就可以了对吧
确实不难,但是就是调了蒟蒻一晚上
为什么调了我一个晚上呢?因为我太弱了:
我把inf设为1000010,这样子的话inf就会过于靠近正常数据导致了inf和正常数据运算影响了结果,若将inf开到2139062143,就不会有这样的问题了
诶,太弱啦!
code
#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(register int i=start;i>=end;--i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define Fa(id) tree[id].f
#define Lson(id) tree[id].son[0]
#define Rson(id) tree[id].son[1]
template<typename T>void read(T &x){
x=0;char r=getchar();T neg=1;
while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
while(r>='0'&&r<='9'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
x*=neg;
}
int n,root=0,nfp=0;
const int maxn=32767+100;
const int inf=2139062143;
struct node{
int son[2];
int f;
int w;
int cnt;
int siz;
}tree[maxn];
inline bool getpos(int id){return ((tree[Fa(id)].son[0]==id)?0:1);}
inline void update(int id){tree[id].siz=tree[Lson(id)].siz+tree[id].cnt+tree[Rson(id)].siz;}
inline void Rotate(int _x){
int _y=tree[_x].f;
int _r=tree[_y].f;
int _pos_y=getpos(_y);
int _pos_x=getpos(_x);
int _change_other=tree[_x].son[_pos_x^1];
tree[_r].son[_pos_y]=_x;
tree[_x].f=_r;
tree[_x].son[_pos_x^1]=_y;
tree[_y].f=_x;
tree[_y].son[_pos_x]=_change_other;
tree[_change_other].f=_y;
update(_y);update(_x);
}
inline void Splay(int id,int to=0){
int f,ff;
while(tree[id].f!=to){
f=Fa(id);ff=Fa(f);
if(ff!=to){
if(getpos(f)==getpos(id))Rotate(f);
else Rotate(id);
}Rotate(id);
}
if(to==0)root=id;
}
inline void Insert(int w){
int cur=root;int p=0;
while(cur&&tree[cur].w!=w){
p=cur;
cur=tree[cur].son[w>tree[cur].w];
}
if(cur)++tree[cur].cnt,Splay(cur);
else{
tree[++nfp].w=w;tree[nfp].cnt=tree[nfp].siz=1;
tree[nfp].f=p;tree[nfp].son[0]=tree[nfp].son[1]=0;
if(p)tree[p].son[tree[p].w<w]=nfp;
Splay(nfp);
}
}
inline void Find(int w){
int cur=root;
while(tree[cur].son[tree[cur].w<w]&&tree[cur].w!=w){
cur=tree[cur].son[tree[cur].w<w];
}
Splay(cur);
}
inline int getpre(int w){
Find(w);
if(tree[root].w<w)return root;
int cur=tree[root].son[0];
while(tree[cur].son[1])
cur=tree[cur].son[1];
Splay(cur);
return cur;
}
inline int getbac(int w){
Find(w);
if(tree[root].w>w)return root;
int cur=tree[root].son[1];
while(tree[cur].son[0])
cur=tree[cur].son[0];
Splay(cur);
return cur;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("datain.txt","r",stdin);
//freopen("debugout2.txt","w",stdout);
#endif // ONLINE_JUDGE
Insert(inf);
Insert(-inf);
read(n);
int res=0;
int ai,pre,bac;
loop(i,1,n){
read(ai);
if(i==1)
res+=ai,Insert(ai);
else{
Find(ai);
if(tree[root].w!=ai){
pre=tree[getpre(ai)].w;
bac=tree[getbac(ai)].w;
res+=min(abs(bac-ai),abs(pre-ai));
}Insert(ai);
}
}printf("%d",res);
return 0;
}