zoukankan      html  css  js  c++  java
  • [BZOJ3223/Tyvj1729]文艺平衡树

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

    Input
    第一行为n,m n表示初始序列有n个数
    这个序列依次是(1,2……n-1,n) m表示翻转操作次数
    接下来m行每行两个数[l,r]
    数据保证 1<=l<=r<=n ,N,M<=100000

    Output
    输出一行n个数字,表示原始序列经过m次变换后的结果

    Sample Input
    5 3
    1 3
    1 3
    1 4

    Sample Output
    4 3 2 1 5


    splay区间操作裸题,区间操作方法请见浅谈算法——splay

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    const int N=1e5;
    int n,m;
    struct Splay{
    	#define T(x) (tree[f[x]][1]==x)
    	int tree[N+10][2],f[N+10],size[N+10];
    	bool flag[N+10];
    	int len,root;
    	void updata(int x){size[x]=size[tree[x][0]]+size[tree[x][1]]+1;}
    	void build(int x){
    		root=x+1;
    		for (int i=1;i<=x;i++)	f[i]=i+1,size[i]=i+1,tree[i+1][0]=i;
    		tree[1][0]=x+2,f[x+2]=1,size[x+2]=1;
    		size[x+1]=x+2;
    	}
    	void move(int x){
    		int fa=f[x],son=tree[x][T(x)^1];
    		tree[x][T(x)^1]=fa;
    		tree[fa][T(x)]=son;
    		if (son)	f[son]=fa;
    		f[x]=f[fa];
    		if (f[x])	tree[f[x]][T(fa)]=x;
    		f[fa]=x;
    		updata(fa),updata(x);
    	}
    	void splay(int x){
    		while (f[x]){
    			if (f[f[x]])	T(x)==T(f[x])?move(f[x]):move(x);
    			move(x);
    		}
    		root=x;
    	}
    	void pushdown(int x){
    		if (!flag[x])	return;
    		swap(tree[x][0],tree[x][1]);
    		flag[tree[x][0]]^=1;
    		flag[tree[x][1]]^=1;
    		flag[x]=0;
    	}
    	int find(int x,int i){
    		pushdown(i);
    		if (size[tree[i][0]]+1==x)	return i;
    		if (x<=size[tree[i][0]])	return find(x,tree[i][0]);
    		return find(x-size[tree[i][0]]-1,tree[i][1]);
    	}
    	void print(int x){
    		if (!x)	return;
    		pushdown(x);
    		print(tree[x][0]);
    		if (x<=n)	printf("%d ",x);
    		print(tree[x][1]);
    	}
    	void work(){
    		int x=read(),y=read();
    		x=find(x,root),splay(x);
    		y=find(y+2,root),splay(y);
    		if (f[x]!=root)	move(x);
    		flag[tree[x][1]]^=1;
    	}
    }T;
    int main(){
    	n=read(),m=read();
    	T.build(n);
    	for (int i=1;i<=m;i++)	T.work();
    	T.print(T.root);
    	return 0;
    }
    
  • 相关阅读:
    springboot ssm propertis 如何搭建多数据源动态切换
    发送验证码
    二维码生成
    文件上传 下载
    git拉代码报错
    通过url 下载文件
    原生JS实现挡板小球游戏
    深入浅出解析AJAX
    深入解析CSS3圆周运动
    JS递归原理
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/9479946.html
Copyright © 2011-2022 走看看