zoukankan      html  css  js  c++  java
  • [ZJOI2006]书架

    fhq treap

    开个minnmaxn作排序标准

    置顶就更新val=--minn,垫底就更新val=++maxn

    改变位置就相当于找前驱后继swap(val1,val2)

    找排名为k的编号就是二叉查找树的模板

    找编号为k前面的书个数就拆树取左边的siz

    #include"cstdio"
    #include"cstring"
    #include"iostream"
    #include"algorithm"
    #include"ctime"
    using namespace std;
    
    const int MAXN=8e4+5;
    
    int n,m,cnt,minn,root,maxn;
    int siz[MAXN],sn[MAXN][2];
    int rev[MAXN],val[MAXN];
    char ch[16];
    
    int cret(int x,int v)
    {
    	siz[x]=1;
    	val[x]=v;
    	rev[x]=rand();
    	sn[x][0]=sn[x][1]=0;
    	return x;
    }
    
    int un(int x,int y)
    {
    	if(!x||!y) return x|y;
    	if(rev[x]<rev[y]){
    		sn[x][1]=un(sn[x][1],y);
    		siz[x]=siz[sn[x][0]]+siz[sn[x][1]]+1;
    		return x;
    	}sn[y][0]=un(x,sn[y][0]);
    	siz[y]=siz[sn[y][0]]+siz[sn[y][1]]+1;
    	return y;
    }
    
    void dro(int k,int v,int &x,int &y)
    {
    	if(!k){x=y=0;return;}
    	if(val[k]<=v) x=k,dro(sn[k][1],v,sn[k][1],y);
    	else y=k,dro(sn[k][0],v,x,sn[k][0]);
    	siz[k]=siz[sn[k][0]]+siz[sn[k][1]]+1;
    	return;
    }
    
    int rnk(int k,int v)
    {
    	if(v<=siz[sn[k][0]]) return rnk(sn[k][0],v);
    	if(v==siz[sn[k][0]]+1) return k;
    	return rnk(sn[k][1],v-siz[sn[k][0]]-1);
    }
    
    void debug()
    {
    	for(int i=1;i<=n;++i) printf("%d ",rnk(root,i));
    	puts("");
    }
    
    void Tp()
    {
    	int v,x,y,z;scanf("%d",&v);
    	dro(root,val[v],x,z),dro(x,val[v]-1,x,y);
    	y=un(sn[y][0],sn[y][1]);root=un(un(x,y),z);
    	--minn;cret(v,minn);
    	dro(root,val[v],x,y);
    	root=un(un(x,v),y);
    	return;
    }
    
    void Bt()
    {
    	int v,x,y,z;scanf("%d",&v);
    	dro(root,val[v],x,z),dro(x,val[v]-1,x,y);
    	y=un(sn[y][0],sn[y][1]);root=un(un(x,y),z);
    	++maxn;cret(v,maxn);
    	dro(root,val[v],x,y);
    	root=un(un(x,v),y);
    	return;
    }
    
    void del(int v)
    {
    	int x,y,z;
    	dro(root,val[v],x,z);dro(x,val[v]-1,x,y);
    	y=un(sn[y][0],sn[y][1]);
    	root=un(un(x,y),z);
    	return;
    }
    
    void Ins()
    {
    	int v,u,x,y,tmp;scanf("%d%d",&v,&u);
    	if(!u) return;
    	if(u==1) dro(root,val[v],x,y),tmp=rnk(y,1),root=un(x,y);
    	else dro(root,val[v]-1,x,y),tmp=rnk(x,siz[x]),root=un(x,y);
    	int v1=val[v],v2=val[tmp];
    	del(v);del(tmp);
    	dro(root,v1,x,y);root=un(un(x,cret(tmp,v1)),y);
    	dro(root,v2,x,y);root=un(un(x,cret(v,v2)),y);
    	return;
    }
    
    void As()
    {
    	int v,x,y;scanf("%d",&v);
    	dro(root,val[v]-1,x,y);
    	printf("%d
    ",siz[x]);
    	root=un(x,y);
    	return;
    }
    
    void Cas()
    {
    	int v,x,y;scanf("%d",&v);
    	printf("%d
    ",rnk(root,v));
    	return;
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);maxn=n;
    	for(int i=1;i<=n;++i){
    		int v,x,y;scanf("%d",&v);
    		dro(root,i,x,y);
    		root=un(un(x,cret(v,i)),y);
    	}while(m--){
    		scanf("%s",ch+1);
    		if(ch[1]=='T') Tp();
    		else if(ch[1]=='B') Bt();
    		else if(ch[1]=='I') Ins();
    		else if(ch[1]=='A') As();
    		else Cas();
    	}return 0;
    }
    
  • 相关阅读:
    September 29th 2017 Week 39th Friday
    September 28th 2017 Week 39th Thursday
    September 27th 2017 Week 39th Wednesday
    September 26th 2017 Week 39th Tuesday
    September 25th 2017 Week 39th Monday
    September 24th 2017 Week 39th Sunday
    angular2 学习笔记 ( Form 表单 )
    angular2 学习笔记 ( Component 组件)
    angular2 学习笔记 ( Http 请求)
    angular2 学习笔记 ( Router 路由 )
  • 原文地址:https://www.cnblogs.com/AH2002/p/10072225.html
Copyright © 2011-2022 走看看