【LG P2286】宠物收养场
这一题属于比较裸的\(\mathrm{Treap}\)了,只需要简单的求前驱和后继(连size
都不用记)
注意事项:
-
可以发现,其实不需要建两棵\(\mathrm{Treap}\)
(当然你想建也没人拦你),只需要建一棵
然后用一个变量\(cnt\)(取值范围包括正负整数)记录\(\mathrm{Treap}\)的情况
(如果\(cnt\)是正整数,表明里面剩余的是动物,反之则是顾客)
然后统计不满意值就可以统一操作了 -
xor
不是逻辑异或,是按位异或!
#include<cstdio>
#include<ctime>
#include<cstdlib>
const int maxn=8e4+2;
struct BTree
{
struct Node
{
int v,idx;
Node* son[2];
void update();
}tree[maxn],*now;
BTree(){now=tree;}
void rotate(Node *&r,int d)
{
Node* tmp=r->son[d^1];
r->son[d^1]=tmp->son[d],tmp->son[d]=r;
r=tmp;return;
}
void insert(Node *&r,int x)
{
if(!r)
{
r=now++;
r->v=x,r->idx=rand(),r->son[0]=r->son[1]=NULL;return;
}
int d=( x>r->v );
insert(r->son[d],x);
if( (r->idx) > (r->son[d]->idx) ) rotate(r,d^1);return;
}
void erase(Node *&r,int x)
{
if(!r) return;
if( r->v==x )
{
if( !r->son[0] and !r->son[1] ) r=NULL;
else if( !r->son[0] xor !r->son[1] )
{
if( !r->son[0] ) r=r->son[1];
else r=r->son[0];
}
else
{
int d=( r->son[0]->idx < r->son[1]->idx );
rotate(r,d),erase(r->son[d],x);
}return;
}
int d=( x>r->v );
erase(r->son[d],x);return;
}
int get_pre(Node *r,int x)
{
if(!r) return -1;
if( r->v==x ) return x;
if( r->v>x ) return get_pre(r->son[0],x);
else
{
int res=get_pre(r->son[1],x);
return ( ~res?res:r->v );
}
}
int get_next(Node* r,int x)
{
if(!r) return -1;
if(r->v==x) return x;
if( r->v<x ) return get_next(r->son[1],x);
else
{
int res=get_next(r->son[0],x);
return ( ~res?res:r->v );
}
}
}bt;
int main()
{
srand(time(0));
int n;scanf("%d",&n);
BTree::Node *root=NULL;
int cnt=0;long long ans=0;
while(n--)
{
int op,x;scanf("%d%d",&op,&x);
if(!op)
{
if( cnt>=0 ) bt.insert(root,x);
else
{
int l=bt.get_pre(root,x),r=bt.get_next(root,x);
if( (l!=-1) xor (r!=-1) )
{
if(~l) ans+=x-l,bt.erase(root,l);
else ans+=r-x,bt.erase(root,r);
}
else
{
if( x-l<=r-x ) ans+=x-l,bt.erase(root,l);
else ans+=r-x,bt.erase(root,r);
}
}cnt++;
}
else
{
if( cnt<=0 ) bt.insert(root,x);
else
{
int l=bt.get_pre(root,x),r=bt.get_next(root,x);
if( (l!=-1) xor (r!=-1) )
{
if(~l) ans+=x-l,bt.erase(root,l);
else ans+=r-x,bt.erase(root,r);
}
else
{
if( x-l<=r-x ) ans+=x-l,bt.erase(root,l);
else ans+=r-x,bt.erase(root,r);
}
}cnt--;
}ans%=(int)1e6;
}
printf("%lld",ans);return 0;
}