学习splay tree的模版题。
网址:http://www.wikioi.com/problem/1296/
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; #define maxn 110000 #define INF 99999999 struct splaytree//封装伸展树 { //maxn:伸展树的点的个数 int pre[maxn];//前驱 int key[maxn];//键值 int ch[maxn][2];//左右孩子 int root,tot;//根节点,节点数量 void init(){ tot=root=0; memset(ch,0,sizeof(ch)); memset(pre,0,sizeof(pre)); memset(key,0,sizeof(key)); } void newnode(int &r,int father,int k){//在r位置,父亲为father,新建一个值为x的新节点。 r=++tot; pre[r]=father; key[r]=k; ch[r][0]=ch[r][1]=0; } void rot(int x,int kind){//kind=1,右旋.kind=0,左旋 int y=pre[x]; ch[y][!kind]=ch[x][kind]; pre[ch[x][kind]]=y; ch[x][kind]=y; if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y]; pre[y]=x; } void splay(int x,int goal){//把x伸展到目标位置 while(pre[x]!=goal){ if(pre[pre[x]]==goal)rot(x,ch[pre[x]][0]==x); else{ int y=pre[x]; int kind=ch[pre[y]][0]==y; if(ch[y][kind]==x){ rot(x,!kind); rot(x,kind); } else{ rot(y,kind); rot(x,kind); } } } if(goal==0)root=x;//把root更新成x } int insert(int x){//插入值x int r=root; while(ch[r][key[r]<x]){ if(key[r]==x){ splay(r,0); return 0; } r=ch[r][key[r]<x]; } newnode(ch[r][x>key[r]],r,x); splay(ch[r][x>key[r]],0); return 1; } int get_pre(int x){//寻找节点x的前驱的值,未找到,反回INF int r=ch[x][0]; if(r==0)return -INF; while(ch[r][1])r=ch[r][1]; return key[r]; } int get_next(int x){//寻找节点x的后继的值,未找到,反回INF int r=ch[x][1]; if(r==0)return INF; while(ch[r][0])r=ch[r][0]; return key[r]; } }tree; int main() { int n,i; while(~scanf("%d",&n)) { int sum=0; int x; tree.init(); for(i=1;i<=n;i++) { if(scanf("%d",&x)==EOF)x=0; if(i==1) { sum+=x; tree.newnode(tree.root,0,x); continue; } if(tree.insert(x)==0)continue; int a=tree.get_pre(tree.root); int b=tree.get_next(tree.root); // cout<<a<<" "<<x<<" "<<b<<endl; sum+=min(x-a,b-x); } printf("%d\n",sum); } return 0; }