3223: Tyvj 1729 文艺平衡树

其实这题好久之前就做过了,毕竟比较水。

嗯很明显是Splay

不过啊

竞赛中有两种常用的平衡树。

1是Splay,2呢,就是Treap了。

于是我今天刚好看见了一个很奇怪的东西。

传说中的非旋转Treap,不过好像只能解决区间问题。

PS:有Splay还要这个干嘛?我真是闲啊。而且这个好像跑得比Splay慢一点。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<algorithm>
#include<cctype>
using namespace std;
template<class T>void read(T &x){
	static char c;
	static bool f;
	for(f=0;c=getchar(),!isdigit(c);)if(c=='-')f=1;
	for(x=0;isdigit(c);c=getchar())x=x*10+c-'0';
	if(f)x=-x;
}
const int N=100000+10;
typedef pair<int,int>droot;
int rnd[N],key[N],sz[N],lc[N],rc[N],root,cnt;
bool rev[N];
void pushup(int x){
	sz[x]=sz[lc[x]]+sz[rc[x]]+1;
}
void pushdown(int x){
	if(rev[x]){
		rev[x]^=1;rev[lc[x]]^=1;rev[rc[x]]^=1;
		swap(lc[x],rc[x]);
	}
}
int merge(int x,int y){
	if(!x||!y)return x+y;
	if(rnd[x]<rnd[y]){
		pushdown(x);
		rc[x]=merge(rc[x],y);
		pushup(x);
		return x;
	}else{
		pushdown(y);
		lc[y]=merge(x,lc[y]);
		pushup(y);
		return y;
	}
}
droot split(int x,int k){
	if(!x)return droot(0,0);
	droot y;pushdown(x);
	if(k<=sz[lc[x]]){
		y=split(lc[x],k);
		lc[x]=y.second;
		y.second=x;
	}else{
		y=split(rc[x],k-sz[lc[x]]-1);
		rc[x]=y.first;
		y.first=x;
	}
	pushup(x);
	return y;
}
int n,st[N];
int build(){
	int x,last;
	int p=0;
	for(int i=0;i<=n+1;i++){
		x=++cnt;
		rnd[x]=rand();
		key[x]=i;
		sz[x]=1;
		lc[x]=rc[x]=0;
		last=0;
		while(p&&rnd[st[p]]>rnd[x]){
			pushup(st[p]);
			last=st[p];
			st[p--]=0;
		}
		if(p)rc[st[p]]=x;
		lc[x]=last;
		st[++p]=x;
	}
	while(p)pushup(st[p--]);
	return st[1];
}
int kth(int k){
	droot x=split(root,k-1);
	droot y=split(x.second,1);
	int ans=y.first;
	root=merge(merge(x.first,ans),y.second);
	return key[ans];
}
int rank(int x,int v){
	if(!x)return 0;
	if(v<key[x])return rank(lc[x],v);
	else return sz[lc[x]]+1+rank(rc[x],v);
}
void insert(int v){
	int k=rank(root,v);
	droot x=split(root,k);
	int y=++cnt;
	rnd[y]=rand();
	key[y]=v;
	sz[y]=1;
	lc[y]=rc[y]=0;
	root=merge(merge(x.first,y),x.second);
}
void del(int k){
	droot x=split(root,k-1);
	droot y=split(root,1);
	root=merge(x.first,y.second);
}
void print(int x){
	if(!x)return;
	pushdown(x);
	print(lc[x]);
	if(key[x]>0&&key[x]<=n)printf("%d ",key[x]);
	print(rc[x]);
}
void rever(int l,int r){
	droot x=split(root,l);
	droot y=split(x.second,r-l+1);
	rev[y.first]^=1;
	root=merge(merge(x.first,y.first),y.second);
}
int main(){
	srand(1453031943);
	int m;read(n);read(m);
	root=build();
	int l,r;
	while(m--){
		read(l);read(r);
		rever(l,r);
	}
	print(root);
	return 0;
}
	


你可能感兴趣的:(3223: Tyvj 1729 文艺平衡树)