HDU3487

#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<algorithm>
#define N 300015
#define inf 1<<29
#define MOD 100000007
#define LL long long
#define Key_value ch[ch[root][1]][0]
#define _match(a,b) ((a)==(b))
using namespace std;
int n,q;
int size[N],pre[N],key[N],num[N],rev[N];
int ch[N][2],tot,root,node[N];
//debug部分copy from hh  
void Treaval(int x) {  
    if(x) {  
        Treaval(ch[x][0]);  
        printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,key = %2d \n",x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);  
        Treaval(ch[x][1]);  
    }  
}  
void debug() {printf("%d\n",root);Treaval(root);}  
//以上Debug  
void NewNode(int &r,int k,int father){
	r=++tot;
	ch[r][0]=ch[r][1]=0;
	pre[r]=father;
	rev[r]=0;
	key[r]=k;
}
void Push_Up(int r){
	size[r]=size[ch[r][0]]+size[ch[r][1]]+1;
}
void Push_Down(int r){
	if(rev[r]){
		swap(ch[r][0],ch[r][1]);
		rev[ch[r][0]]^=1;
		rev[ch[r][1]]^=1;
		rev[r]=0;		
	}
}
void Bulid(int &r,int L,int R,int father){
	if(L>R)
		return ;
	int mid=(L+R)/2;
	NewNode(r,mid,father);
	Bulid(ch[r][0],L,mid-1,r);
	Bulid(ch[r][1],mid+1,R,r);
	Push_Up(r);
}
void Init(){
	tot=root=0;
	ch[root][0]=ch[root][1]=pre[root]=rev[root]=size[root]=0;
	NewNode(root,-1,0);
	NewNode(ch[root][1],-1,root);
	size[root]=2;
	Bulid(Key_value,1,n,ch[root][1]);
	Push_Up(ch[root][1]);
	Push_Up(root);
}
void Rotate(int x,int kind){  
	int y=pre[x];    
	Push_Down(y);
	Push_Down(x);
	ch[y][!kind]=ch[x][kind];   
	pre[ch[x][kind]]=y;  
	if(pre[y])  
		ch[pre[y]][ch[pre[y]][1]==y]=x;  
	pre[x]=pre[y];  
	ch[x][kind]=y;  
	pre[y]=x;  
	Push_Up(y);  
}   
void Splay(int r,int goal){  
	Push_Down(r);
	while(pre[r]!=goal){  
		int y = pre[r];int z = pre[y];
		Push_Down(z);Push_Down(y);Push_Down(r);
		if(pre[pre[r]]==goal)  
			Rotate(r,ch[pre[r]][0]==r);  
		else{  
			int y=pre[r];  
			int kind=(ch[pre[y]][0]==y);  
			if(ch[y][kind]==r){  
				Rotate(r,!kind);  
				Rotate(r,kind);  
			}  
			else{  
				Rotate(y,kind);  
				Rotate(r,kind);  
			}  
		}  
	}  
	Push_Up(r);  
	if(goal==0) root=r;  
} 
int Get_Kth(int r,int k){
	Push_Down(r);
	int t=size[ch[r][0]];
	if(t==k-1)
		return r;
	if(t>=k)
		return Get_Kth(ch[r][0],k);
	else
		return Get_Kth(ch[r][1],k-t-1);
}
int Get_Min(int r){
	Push_Down(r);
	while(ch[r][0]){
		r=ch[r][0];
		Push_Down(r);
	}
	return r;
}
int Get_Max(int r){
	Push_Down(r);
	while(ch[r][1]){
		r=ch[r][1];
		Push_Down(r);
	}
	return r;
}
void Reversal(int a,int b){
	int x=Get_Kth(root,a);
	int y=Get_Kth(root,b+2);
	Splay(x,0);
	Splay(y,root);		
	rev[Key_value]^=1;
}
void Cut(int a,int b,int c){
	int x=Get_Kth(root,a);
	int y=Get_Kth(root,b+2);	
	Splay(x,0);
	Splay(y,root);
	int tmp=Key_value;
	Key_value=0;
	Push_Up(ch[root][1]);
	Push_Up(root);
	int z=Get_Kth(root,c+1);
	Splay(z,0);
	int m=Get_Min(ch[root][1]);
	Splay(m,root);
	Key_value=tmp;
	pre[Key_value]=ch[root][1];
	Push_Up(ch[root][1]);
	Push_Up(root);
}
int cnt;
void InOrder(int r){
	if(r==0)
		return;
	Push_Down(r);
	InOrder(ch[r][0]);
	if(cnt>=1&&cnt<=n){
	    if(cnt>1) printf(" ");
    	printf("%d",key[r]);
	}
	cnt++;
	InOrder(ch[r][1]);
}	
int main(){
	while(scanf("%d%d",&n,&q)!=EOF){
		if(n==-1&&q==-1)
			break;
		Init();
		while(q--){
			char str[10];
			int a,b,c;
			scanf("%s",str);		
			if(str[0]=='C'){
				scanf("%d%d%d",&a,&b,&c);
				Cut(a,b,c);
			}
			else{
				scanf("%d%d",&a,&b);
				Reversal(a,b);
			}
		}	
		cnt=0;
		InOrder(root);
		printf("\n");
	}
	return 0;
}



风格更新后:(PS:注意很多函数里面要先PushDown)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 600010
#define LL long long int
#define Key_value ch[ch[root][1]][0]
#define MOD 100000007;
int n,q;
struct SplayTree
{
	int pre[maxn],ch[maxn][2],size[maxn],key[maxn],flip[maxn],root,cnt,pos;

	void Treaval(int r)
	{
		if(r)
		{
			Treaval(ch[r][0]);
			printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d,key = %2d \n",r,ch[r][0],ch[r][1],pre[r],size[r],key[r]);
			Treaval(ch[r][1]);
		}
	}

	void Debug()
	{
		printf("%d\n",root);
		Treaval(root);
	}

	void init()
	{
		root = cnt = pos = 0;
		pre[0] = ch[0][0] = ch[0][1] = 0;
		size[0] = key[0] = flip[0] = 0;
		NewNode(root,0,-1);
		NewNode(ch[root][1],root,-1);
		size[root] = 2;
		BuildTree(Key_value,1,n,ch[root][1]);
		PushUp(ch[root][1]);
		PushUp(root);
	}

	void BuildTree(int & x,int l,int r,int father)
	{
		if(l > r)	return;
		int mid = (l+r) >> 1;
		NewNode(x,father,mid);
		if(l < mid)
			BuildTree(ch[x][0],l,mid-1,x);
		if(r > mid)
			BuildTree(ch[x][1],mid+1,r,x);
		PushUp(x);
	}

	void NewNode(int & r,int father,int k)
	{
		r = ++cnt;
		pre[r] = father;
		ch[r][0] = ch[r][1] = 0;
		flip[r] = 0;
		key[r] = k;
	}

	void PushDown(int r)
	{
		if(flip[r])
		{
			swap(ch[r][0],ch[r][1]);
			flip[ch[r][0]] ^= 1;
			flip[ch[r][1]] ^= 1;
			flip[r] = 0;
		}
	}

	void PushUp(int r)
	{
		size[r] = size[ch[r][0]] + size[ch[r][1]] + 1;
	}

	int Get_Next(int r)
	{
		PushDown(r);
		int tmp = ch[r][1];
		if(tmp == 0)	return inf;
		PushDown(tmp);
		while(ch[tmp][0])
		{
			tmp = ch[tmp][0];
			PushDown(tmp);
		}
		return tmp;
	}

	void Rotate(int x,int kind)
	{
		int y = pre[x];
		PushDown(y);
		PushDown(x);
		ch[y][!kind] = ch[x][kind];
		pre[ch[x][kind]] = y;
		if(pre[y])
			ch[pre[y]][ch[pre[y]][1]==y] = x;
		pre[x] = pre[y];
		ch[x][kind] = y;
		pre[y] = x;
		PushUp(y);
	}

	void Splay(int r,int goal)
	{
		PushDown(r);
		while(pre[r] != goal)
		{
			int y = pre[r],z = pre[y];
			PushDown(z);	PushDown(y);	PushDown(r);
			if(pre[pre[r]] == goal)
			{
				Rotate(r,ch[pre[r]][0]==r);
			}
			else
			{
				int kind = ch[pre[y]][0] == y;
				if(ch[y][kind] == r)
				{
					Rotate(r,!kind);
					Rotate(r,kind);
				}
				else
				{
					Rotate(y,kind);
					Rotate(r,kind);
				}
			}
		}
		PushUp(r);
		if(goal == 0)	root = r;
	}
	
	int Get_Kth(int r,int k)
	{
		PushDown(r);
		int t = size[ch[r][0]];
		if(k <= t)
			return Get_Kth(ch[r][0],k);
		else if(k <= t + 1)
			return r;
		else return Get_Kth(ch[r][1],k-t-1);
	}

	void Reversal(int a,int b)
	{
		int x = Get_Kth(root,a);
		int y = Get_Kth(root,b+2);
		Splay(x,0);
		Splay(y,root);
		flip[Key_value] ^= 1;
	}

	void Cut(int a,int b,int c)
	{
		int x = Get_Kth(root,a);
		int y = Get_Kth(root,b+2);
		Splay(x,0);
		Splay(y,root);
		int tmp = Key_value;
		Key_value = 0;
		PushUp(ch[root][1]);
		PushUp(root);
		int z = Get_Kth(root,c+1);
		Splay(z,0);
		int m = Get_Next(root);
		Splay(m,root);
		Key_value = tmp;
		pre[Key_value] = ch[root][1];
		PushUp(ch[root][1]);
		PushUp(root);
	}

	void InOrder(int r)
	{
		if(r == 0)
			return;
		PushDown(r);
		InOrder(ch[r][0]);
		if(pos >= 1 && pos <= n)
		{
			if(pos > 1)	printf(" ");
			printf("%d",key[r]);
		}
		pos++;
		InOrder(ch[r][1]);
	}

	void solve()
	{
		init();
		while(q--)
		{
			char str[10];
			int a,b,c;
			scanf("%s",str);
			if(str[0] == 'C')
			{
				scanf("%d%d%d",&a,&b,&c);
				Cut(a,b,c);
			}
			else 
			{
				scanf("%d%d",&a,&b);
				Reversal(a,b);
			}
		}
		pos = 0;
		InOrder(root);
		printf("\n");
	}
}spt;

int main()
{
	while(scanf("%d%d",&n,&q)!=EOF)
	{
		if(n == -1 && q == -1)
			break;
		spt.solve();
	}
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值