# bzoj1208 宠物收养所

5
0 2
0 4
1 3
1 2
1 5

## Sample Output

3
(abs(3-2) + abs(2-4)=3，最后一个领养者没有宠物可以领养)

Treap，求一下前驱和后继就行。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#define in(a) a=read()
#define MAXN 80010
#define REP(i,k,n)  for(int i=k;i<=n;i++)
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar())
if(ch='-')
f=-1;
for(;isdigit(ch);ch=getchar())
x=x*10+ch-'0';
return x*f;
}
int n,has,book;
int root,total,ans;
struct node{
int l,r,size,c,key,data;
}tree[MAXN];
inline int ran(){
int t=(rand()+19260817)%2147483647;
return (t*10000007LL)%2147483647;
}
inline void update(int i){
tree[i].size=tree[tree[i].l].size+tree[tree[i].r].size+tree[i].c;
return ;
}
inline void zag(int &i){
int t=tree[i].r;
tree[i].r=tree[t].l;
tree[t].l=i;
tree[t].size=tree[i].size;
update(i);
i=t;
return ;
}
inline void zig(int &i){
int t=tree[i].l;
tree[i].l=tree[t].r;
tree[t].r=i;
tree[t].size=tree[i].size;
update(i);
i=t;
return ;
}
inline void insert(int &i,int k){
if(!i){
i=++total;
tree[i].key=ran();
tree[i].c=tree[i].size=1;
tree[i].data=k;
return ;
}
tree[i].size++;
if(tree[i].data==k)  tree[i].c++;
else  if(tree[i].data>k){
insert(tree[i].l,k);
if(tree[tree[i].l].key<tree[i].key)  zig(i);
}
else{
insert(tree[i].r,k);
if(tree[tree[i].r].key<tree[i].key)  zag(i);
}
return ;
}
inline void delate(int &i,int k){
if(!i)  return ;
if(tree[i].data==k){
if(tree[i].c>1)  tree[i].c--,tree[i].size--;
else{
if(!tree[i].l || !tree[i].r)  i=tree[i].l+tree[i].r;
else  if(tree[tree[i].l].key<tree[tree[i].r].key)  zig(i),delate(i,k);
else  zag(i),delate(i,k);
}
}
else if(k<tree[i].data)  tree[i].size--,delate(tree[i].l,k);
else  tree[i].size--,delate(tree[i].r,k);
return ;
}
inline int getfront(int i,int k){
if(!i)  return -214748364;
if(k>=tree[i].data)  return max(tree[i].data,getfront(tree[i].r,k));
else  return getfront(tree[i].l,k);
}
inline int getback(int i,int k){
if(!i)  return 214748364;
if(k<=tree[i].data)  return min(tree[i].data,getback(tree[i].l,k));
else  return getback(tree[i].r,k);
}
int main(){
in(n);
int a,b;
REP(i,1,n){
in(a),in(b);
if(!has){
insert(root,b);
book=a,has=1;
continue;
}
if(a!=book){
int k1=getfront(root,b);
int k2=getback(root,b);
if(abs(k1-b)>abs(k2-b)){
ans=(ans+abs(k2-b))%1000000;
delate(root,k2);
has--;
}
else{
ans=(ans+abs(k1-b))%1000000;
delate(root,k1);
has--;
}
continue;
}
if(a==book)  insert(root,b),has++;
}
printf("%d",ans);
return 0;
}

posted @ 2018-12-10 16:19  Dijkstra·Liu  阅读(231)  评论(0编辑  收藏  举报