• BZOJ3223 Tyvj 1729 文艺平衡树 splay


    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - BZOJ3223


    题意概括

      您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 

      数据范围:n<=100000


    题解

      splay裸题。

      加两个哨兵节点。

      还有pushdown标记


    代码

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    using namespace std;
    const int N=100005;
    int n,m;
    struct Splay{
    	int fa[N],son[N][2],rev[N],val[N],size[N],tot,root;
    	void clear(){
    		tot=root=0;
    		memset(fa,0,sizeof fa);
    		memset(son,0,sizeof son);
    		memset(rev,0,sizeof rev);
    	}
    	void clear(int x,int v){
    		val[x]=v;
    		fa[x]=son[x][0]=son[x][1]=rev[x]=0;
    		size[x]=1;
    	}
    	void pushup(int rt){
    		int &ls=son[rt][0],&rs=son[rt][1];
    		size[rt]=size[ls]+size[rs]+1;
    	}
    	void pushdown(int rt){
    		int &ls=son[rt][0],&rs=son[rt][1];
    		if (!rev[rt])
    			return;
    		rev[rt]=0;
    		rev[ls]^=1;
    		rev[rs]^=1;
    		swap(ls,rs);
    	}
    	void rec_fa(int rt,int s,int p){
    		son[rt][p]=s;
    		fa[s]=rt;
    	}
    	int getp(int rt){
    		return son[fa[rt]][1]==rt;
    	}
    	void rotate(int x){
    		int y=fa[x],z=fa[y],p=getp(x);
    		rec_fa(z,x,getp(y));
    		rec_fa(y,son[x][!p],p);
    		rec_fa(x,y,!p);
    		pushup(y);
    		pushup(x);
    	}
    	void down(int rt){
    		if (fa[rt])
    			down(fa[rt]);
    		pushdown(rt);
    	}
    	void splay(int x,int anst){
    		down(x);
    		if (anst==0)
    			root=x;
    		for (int y=fa[x];fa[x]!=anst;rotate(x),y=fa[x])
    			if (fa[y]!=anst)
    				rotate(getp(x)==getp(y)?y:x);
    	}
    	int build(int L,int R){
    		if (L>R)
    			return 0;
    		int rt=++tot,mid=(L+R)>>1;
    		clear(rt,(1<=mid&&mid<=n)?mid:-1);
    		int &ls=son[rt][0],&rs=son[rt][1];
    		ls=build(L,mid-1);
    		rs=build(mid+1,R);
    		fa[ls]=fa[rs]=rt;
    		pushup(rt);
    		return rt;
    	}
    	int find(int x,int k){//find kth
    		pushdown(x);
    		int &ls=son[x][0],&rs=son[x][1];
    		if (size[ls]+1==k)
    			return x;
    		if (size[ls]+1>k)
    			return find(ls,k);
    		if (size[ls]+1<k)
    			return find(rs,k-size[ls]-1);
    	}
    	void answer(int rt){
    		pushdown(rt);
    		int &ls=son[rt][0],&rs=son[rt][1];
    		if (ls)
    			answer(ls);
    		if (val[rt]!=-1)
    			printf("%d ",val[rt]);
    		if (rs)
    			answer(rs);
    	}
    }s;
    int main(){
    	scanf("%d%d",&n,&m);
    	s.clear();
    	s.root=s.build(0,n+1);
    	for (int i=1,L,R;i<=m;i++){
    		scanf("%d%d",&L,&R);
    		int x=s.find(s.root,L),y=s.find(s.root,R+2);
    		s.splay(x,0);
    		s.splay(y,x);
    		s.rev[s.son[y][0]]^=1;
    	}
    	s.answer(s.root);
    	return 0;
    }
    /*
    5 3
    1 3
    1 3
    1 4
    */
    

      

  • 相关阅读:
    Censored! POJ
    POJ
    HDU
    ionic中的生命周期函数
    ionic项目相关的操作命令
    数组的join()函数操作
    pop()实现逐个删除数组最后一位并输出
    CSS制作彩虹效果
    ionic2 页面加载时图片添加的问题
    升级ionic版本后,创建新项目报Error Initializing app错误解决
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ3223.html
Copyright © 2020-2023  润新知