zoukankan      html  css  js  c++  java
  • 【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;
    }
    
  • 相关阅读:
    判断单链表中是否有环,找到环的入口节点的理论证明
    交叉熵代价函数(作用及公式推导)
    C#调用C++、Opencv的Dll
    腾讯机器学习一面面经
    C#调用C++类库的几种方式
    2017年腾讯基础研究笔试感受
    关于开源库或者SDK的文档问题
    卷积神经网络Lenet-5实现
    NULL、0、nullptr 区别分析
    C++中,new/delete和malloc/free的区别
  • 原文地址:https://www.cnblogs.com/info---tion/p/13380559.html
Copyright © 2011-2022 走看看