【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;
}
上一篇:EMC中的单位


下一篇:多项式全家桶