累加器传送门:
http://blog.csdn.net/NOIAu/article/details/71775000
splay裸题,就不写题解了,贴个友联,然后直接贴我代码
友链:
http://blog.csdn.net/skydec/article/details/20151805
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#define MAXN 100000+10
using namespace std;
int n,root=0,ans,sz,temp;
int x1,y1,sum;
bool judge;
int ABS(int x){return x>0?x:-x;}
struct Splay_Tree{
int val,wei,size,lson,rson,fa;
}tree[MAXN];
void update(int k){
tree[k].size=tree[tree[k].lson].size+tree[tree[k].rson].size+tree[k].wei;
}
void Right_Rotato(int x){
int y=tree[x].fa;
int z=tree[y].fa;
tree[y].lson=tree[x].rson;
if(tree[x].rson!=-1)
tree[tree[x].rson].fa=y;
tree[x].fa=z;
if(z){
if(tree[z].lson==y) tree[z].lson=x;
else tree[z].rson=x;
}
tree[x].rson=y;tree[y].fa=x;
update(y);
update(x);
}
void Left_Rotato(int x){
int y=tree[x].fa;
int z=tree[y].fa;
tree[y].rson=tree[x].lson;
if(tree[x].lson!=-1)
tree[tree[x].lson].fa=y;
tree[x].fa=z;
if(z){
if(tree[z].lson==y) tree[z].lson=x;
else tree[z].rson=x;
}
tree[x].lson=y;tree[y].fa=x;
update(y);
update(x);
}
void splay(int x,int Ancestry){
while(tree[x].fa!=Ancestry){
int y=tree[x].fa;int z=tree[y].fa;
if(z==Ancestry){
if(tree[y].lson==x) Right_Rotato(x);
else Left_Rotato(x);
}else{
if(tree[z].lson==y&&tree[y].lson==x){Right_Rotato(y);Right_Rotato(x);}//
else if(tree[z].rson==y&&tree[y].rson==x){Left_Rotato(y);Left_Rotato(x);}//
else if(tree[z].rson==y&&tree[y].lson==x){Right_Rotato(x);Left_Rotato(x);}//
else if(tree[z].lson==y&&tree[y].rson==x){Left_Rotato(x);Right_Rotato(x);}
}
}
if(Ancestry==0) root=x;
}
void insert(int x,int k){
if(x==tree[k].val){
tree[k].wei++;
splay(k,0);
return;
}else if(x>tree[k].val){
if(tree[k].rson==-1){
tree[k].rson=++sz;
tree[sz].fa=k;
tree[sz].val=x;
tree[sz].wei=tree[sz].size=1;
tree[sz].lson=tree[sz].rson=-1;
splay(sz,0);return;
}else{
insert(x,tree[k].rson);return;
}
}else{
if(tree[k].lson==-1){
tree[k].lson=++sz;
tree[sz].fa=k;
tree[sz].val=x;
tree[sz].wei=tree[sz].size=1;
tree[sz].lson=tree[sz].rson=-1;
splay(sz,0);return;
}else{
insert(x,tree[k].lson);return;
}
}
}
void query_Pre(int temp,int k){
if(k==-1) {if(x1==-1) judge=false;return;}
if(temp==tree[k].val&&tree[k].wei>1) x1=k;
else if(temp>tree[k].val) x1=k,query_Pre(temp,tree[k].rson);
else query_Pre(temp,tree[k].lson);
}
void query_Aft(int temp,int k){
if(k==-1) {if(y1==-1) judge=false;return;}
if(temp==tree[k].val&&tree[k].wei>1) y1=k;
else if(temp<tree[k].val) y1=k,query_Aft(temp,tree[k].lson);
else query_Aft(temp,tree[k].rson);
}
int query(int temp){
x1=-1;y1=-1;int a,b;
judge=true;
query_Pre(temp,root);
if(!judge) a=0x7fffffff;
else a=ABS(tree[x1].val-temp);
judge=true;
query_Aft(temp,root);
if(!judge) b=0x7fffffff;
else b=ABS(tree[y1].val-temp);
int minn=min(a,b);
return minn;
}
int main(){
ios::sync_with_stdio(false);
scanf("%d",&n);
scanf("%d",&temp);
sum+=temp;
tree[++sz].val=temp;
tree[sz].size=tree[sz].wei=1;tree[sz].lson=tree[sz].rson=-1;
tree[sz].fa=0;root=sz;
for(register int i=2;i<=n;i++){
scanf("%d",&temp);
insert(temp,root);
sum+=query(temp);
}
printf("%d",sum);
return 0;
}
该代码是自己yy出来的,注意有一点,有可能有重复数据,这个时候的前趋可能是自己,另外,如果在当前数里没有比其大的,则该数的后驱就设为极大值即可,前驱同理