数据有误,,,读入文件不完整...所以到后面会没有数可以读..无语了...真是奇葩...
这道题线段树离线也可以做吧...我开始用treap做.结果超时了...splay还是强啊...代码..参考了几个大神的..haha593572013 、 胡浩大神
Program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<time.h>
#include<map>
#include<algorithm>
#define ll long long
#define eps 1e-5
#define oo 1<<30
#define pi acos(-1.0)
#define MAXN 300015
using namespace std;
struct Splay_tree
{
int key[MAXN],son[MAXN][2],pre[MAXN];
int root,num;
void initial()
{
root=num=pre[0]=son[0][0]=son[0][1]=0;
addnode(root,-oo);
addnode(son[root][1],oo);
pre[num]=root;
}
void addnode(int &k,int c)
{
k=++num;
key[k]=c,son[k][0]=son[k][1]=0;
}
void rot(int x,int tp)
{
int y=pre[x];
son[y][!tp]=son[x][tp];
pre[son[x][tp]]=y;
pre[x]=pre[y];
if(pre[x]) son[pre[y]][son[pre[y]][1]==y]=x;
son[x][tp]=y;
pre[y]=x;
}
void splay(int x)
{
while(pre[x])
{
if(!pre[pre[x]]) rot(x,son[pre[x]][0]==x);
else
{
int y=pre[x],z=pre[y];
int f=(son[z][0]==y);
if(son[y][f]==x) rot(x,!f),rot(x,f);
else rot(y,f),rot(x,f);
}
}
root=x;
}
void insert(int &k,int KEY,int father)
{
if (!k)
{
addnode(k,KEY);
pre[k]=father;
splay(k);
return;
}
if (KEY==key[k]) { splay(k); return; }
if (KEY<key[k]) insert(son[k][0],KEY,k);
else insert(son[k][1],KEY,k);
}
void findpre(int x,int c,int &ans)
{
if (!x) return;
if(key[x]<=c)
{
ans=key[x];
findpre(son[x][1],c,ans);
}else
findpre(son[x][0],c,ans);
}
void findsucc(int x,int c,int &ans)
{
if(!x) return ;
if(key[x]>=c)
{
ans=key[x];
findsucc(son[x][0],c,ans);
} else
findsucc(son[x][1],c,ans);
}
int findans(int c)
{
int x,y;
findpre(root,c,x);
findsucc(root,c,y);
if(abs(x-c)<=abs(y-c))
{
if(x!=-oo) return abs(x-c);
}
else
if(y!=oo) return abs(y-c);
}
}st;
int main()
{
int n,p,x,ans=0;
scanf("%d",&n);
st.initial();
scanf("%d",&x);
st.insert(st.root,x,0);
ans=x;
for (p=2;p<=n;p++)
{
while (scanf("%d",&x)==EOF) x=0;
ans+=st.findans(x);
st.insert(st.root,x,0);
}
printf("%d\n",ans);
return 0;
}