数据有误,,,读入文件不完整...所以到后面会没有数可以读..无语了...真是奇葩...
这道题线段树离线也可以做吧...我开始用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; }