zoukankan      html  css  js  c++  java
  • [洛谷P2286][题解][HNOI2004]宠物收养场

    题目

    0.写在前面

    终于靠这道题完成了寒假以来十棵平衡树的flag。。。
    特著此题解以纪念

    1.思路

    可能有人会想到维护两个平衡树,但当你读过题之后就会发现:
    人和宠物本质是一样的!!!
    所以,写一棵就够了。
    其他的都是模板,相信做到这种题的巨佬肯定都会了,不做细讲。
    领养/被领养的步骤按题意模拟即可。

    2.细节

    关于平衡树的选用随便啦~反正我是 Splay 党~
    取领养/被领养的家伙的时候要注意取等号!!!

    3.代码

    缺省源?自己找!

    #define N 80010
    #define mod 1000000
    int n,root,tot,ans;//有人说ans要LL,其实膜好了不需要LL的 
    int fa[N],ch[N][2];
    int data[N],siz[N];
    int st;//来人+1,来宠物-1
    
    //-----*平衡树基本操作始*-----// 
    inline int Son(int k){
    	return ch[fa[k]][1]==k;
    }
    inline void Pushup(int k){
    	siz[k]=siz[ls]+siz[rs]+1;
    }
    inline void Rotate(int k){
    	int fk=fa[k],gfk=fa[fk];
    	int b=Son(k),c=Son(fk),a=ch[k][!b];
    	ch[gfk][c]=k,fa[k]=gfk;
    	ch[fk][b]=a,fa[a]=fk;
    	ch[k][!b]=fk,fa[fk]=k;
    	Pushup(k),Pushup(fk);
    }
    inline void Splay(int k,int to=0){
    	while(fa[k]!=to){
    		int fk=fa[k],gfk=fa[fk];
    		if(gfk!=to){
    			if(Son(k)==Son(fk))Rotate(fk);
    			else Rotate(k);
    		}
    		Rotate(k);
    	}
    	if(!to)root=k;
    }
    inline void Insert(int num){
    	int k=root,tmp=0;
    	while(k&&data[k]!=num){
    		tmp=k,k=ch[k][num>data[k]];
    	}
    	if(!k){
    		k=++tot;
    		if(tmp)ch[tmp][num>data[tmp]]=k;
    		fa[k]=tmp,data[k]=num;
    		ls=rs=0;
    	}
    	Splay(k);
    }
    inline void Find(int num){
    	int k=root;
    	while(data[k]!=num&&ch[k][num>data[k]]){
    		k=ch[k][num>data[k]];
    	}
    	Splay(k);
    }
    inline int Get(int num,int opt){
    	Find(num);
    	int k=root;
    	if(opt&&num<data[k])return k;
    	if(!opt&&num>data[k])return k;
    	k=ch[k][opt];
    	while(ch[k][opt^1])k=ch[k][opt^1];
    	return k;
    }
    inline int Gete(int num,int opt){
    	Find(num);
    	int k=root;
    	if(opt&&num<=data[k])return k;
    	if(!opt&&num>=data[k])return k;
    	k=ch[k][opt];
    	while(ch[k][opt^1])k=ch[k][opt^1];
    	return k;
    }
    inline void Delete(int num){
    	int l=Get(num,0),r=Get(num,1);
    	Splay(l),Splay(r,l);
    	ch[r][0]=0;
    }
    //-----*平衡树基本操作完*-----// 
    
    int main(){
    	Insert(-INF),Insert(INF);//防爆基本操作 
    	Read(n);
    	for(rg int i=1;i<=n;i++){
    		int opt,num;
    		Read(opt),Read(num);
    		if(st==0)Insert(num);//空了 
    		else if(st<0){//全是宠物 
    			if(opt==1)Insert(num);
    			else {
    				int pred=data[Gete(num,0)];
    				int sufd=data[Gete(num,1)];
    				if(abs(pred-num)<=abs(sufd-num)){
    					ans=(ans+abs(pred-num))%mod;
    					Delete(pred);
    				}else {
    					ans=(ans+abs(sufd-num))%mod;
    					Delete(sufd);
    				}
    			}
    		}else {//全是人 
    			if(opt==0)Insert(num);
    			else {
    				int pred=data[Gete(num,0)];
    				int sufd=data[Gete(num,1)];
    				if(abs(pred-num)<=abs(sufd-num)){
    					ans=(ans+abs(pred-num))%mod;
    					Delete(pred);
    				}else {
    					ans=(ans+abs(sufd-num))%mod;
    					Delete(sufd);
    				}
    			}
    		}
    		st+=(opt==0)?1:-1;
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    

    4.完结撒花

  • 相关阅读:
    致命错误: mysql/mysql.h:没有那个文件或目录 解决办法
    [转载]解决/usr/bin/ld: cannot find lxxx 问题
    mysql5.5.25a安装:Installation of system tables failed解决办法
    ubuntu源码编译安装mysql5.5.25a
    ubuntu 11.10 安装配置NFS
    nrpe简单插件编写
    我也学erlang(五)——简单的列表处理
    C语言中自加与自减效率的思考
    DBI connect() failed: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'
    std::ostream_iterator用法
  • 原文地址:https://www.cnblogs.com/juruoajh/p/12818923.html
Copyright © 2011-2022 走看看