题目链接http://begin.lydsy.com/JudgeOnline/problem.php?id=2929
记录一下SBT的模版...
(Ps:题目有坑!)
#include <iostream>
#include <cstdio>
#include <string.h>
#include <cmath>
#include <map>
#include <climits>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
int T,n,m;
struct SBT{
int left,right,size,data;
}tree[maxn];
int top,root;
void left_rot(int &x){
int y=tree[x].right;
tree[x].right=tree[y].left;
tree[y].left=x;
tree[y].size=tree[x].size;
tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
x=y;
}
void right_rot(int &x){
int y=tree[x].left;
tree[x].left=tree[y].right;
tree[y].right=x;
tree[y].size=tree[x].size;
tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
x=y;
}
void Maintain(int &x,bool flag){
if (!flag){
if (tree[tree[tree[x].left].left].size>tree[tree[x].right].size)
right_rot(x);
else
if (tree[tree[tree[x].left].right].size>tree[tree[x].right].size)
left_rot(tree[x].left),right_rot(x);
else
return;
}
else{
if (tree[tree[tree[x].right].right].size>tree[tree[x].left].size)
left_rot(x);
else
if (tree[tree[tree[x].right].left].size>tree[tree[x].left].size)
right_rot(tree[x].right),left_rot(x);
else
return;
}
Maintain(tree[x].left,0);
Maintain(tree[x].right,1);
Maintain(x,1);
Maintain(x,0);
}
void insert(int &x,int data){
if (x==0){
x=++top;
tree[x].size=1;
tree[x].left=tree[x].right=0;
tree[x].data=data;
}
else{
tree[x].size++;
if (data<tree[x].data) insert(tree[x].left,data);
else insert(tree[x].right,data);
Maintain(x,data>=tree[x].data);
}
}
int remove(int &x,int data){
tree[x].size--;
if (data>tree[x].data)
remove(tree[x].right,data);
else
if (data<tree[x].data)
remove(tree[x].left,data);
else{
if (tree[x].left!=0&&tree[x].right==0){
int ret=x;
x=tree[x].left;
return x;
}
else
if (tree[x].right!=0&&tree[x].left==0){
int ret=x;
x=tree[x].right;
return x;
}
else
if (tree[x].left==0&&tree[x].right==0){
int ret=x;
x=0;
return ret;
}
else{
int ret=tree[x].right;
while (tree[ret].left) ret=tree[x].left;
tree[x].data=tree[ret].data;
remove(tree[x].right,tree[ret].data);
}
}
}
int select(int &x,int k){
int r=tree[tree[x].left].size+1;
if (k<r) return select(tree[x].left,k);
else
if (k>r) return select(tree[x].right,k-r);
else
return tree[x].data;
}
int Rank(int &x,int data){
if (x==0) return 0;
if (data>tree[x].data) return tree[tree[x].left].size+1+Rank(tree[x].right,data);
else if (data<tree[x].data) return Rank(tree[x].left,data);
else return tree[tree[x].left].size+1;
}
int prev(int &x,int y,int v){
if(!x)return v;
if(v<=tree[x].data) return prev(tree[x].left,y,v);
else{
int tmp=prev(tree[x].right,x,v);
return tmp==v?tree[x].data:tmp;
}
}
int succ(int &x,int y,int v){
if(!x)return v;
if(v>=tree[x].data) return succ(tree[x].right,y,v);
else{
int tmp=succ(tree[x].left,x,v);
return tmp==v?tree[x].data:tmp;
}
}
int getmin(){
int x=root;
while (tree[x].left) x=tree[x].left;
return tree[x].data;
}
int getmax(){
int x=root;
while (tree[x].right) x=tree[x].right;
return tree[x].data;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
#endif
int x,p,q;
while(~scanf("%d%d",&n,&x)){
map<int,int>mp;
root = top = 0;
int sum=x;
insert(root,x);
mp[x]=1;
for(int i=2;i<=n;i++){
if(scanf("%d",&x)==EOF)
x=0;
if(mp[x]) continue;
if(!(p=x-prev(root,0,x))) p=INT_MAX;
if(!(q=succ(root,0,x)-x)) q=INT_MAX;
sum+=min(p,q);
insert(root,x);
mp[x]=1;
}
printf("%d\n",sum);
}
return 0;
}