splay树模版


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 100010;
int pre[maxn], ch[maxn][2], sz[maxn], rev[maxn];
int root, top1;

int val[maxn];

void rever(int x)
{
	if(!x)
		return;
	swap(ch[x][0], ch[x][1]);
	rev[x] ^= 1;
}
void pushdown(int x)
{
	if(!x)
		return;
	if(rev[x])
	{
		rever(ch[x][0]);
		rever(ch[x][1]);
		rev[x] = 0;
	}
}

void pushup(int x)
{
    sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1;
}
void rotate(int x, int d)
{
    int y = pre[x];
    pushdown(y);
    pushdown(x);
    ch[y][d^1] = ch[x][d];
    pre[ch[x][d]] = y;
    if(pre[y])
        ch[pre[y]][ch[pre[y]][1] == y] = x;
    pre[x] = pre[y];
    ch[x][d] = y;
    pre[y] = x;
    pushup(y);
    
}

void splay(int x, int goal)
{
    pushdown(x);
    while(pre[x] != goal)
    {
        if(pre[pre[x]] == goal)
        {
            rotate(x, ch[pre[x]][0] == x);
        }
        else
        {
            int y = pre[x], z = pre[y];
            int d = (ch[z][0] == y);
            if(ch[y][d] == x)
            {
                rotate(x, d^1);
                rotate(x, d);
            }
            else
            {
                rotate(y, d);
                rotate(x, d);
            }
        }
    }
    pushup(x);
    if(goal == 0)
        root = x;
}


void NewNode(int &x, int f, int c)
{
    x = ++top1;
    ch[x][0] = ch[x][1];
    sz[x] = 1;
    pre[x] = f;
	
	val[x] = c;
	rev[x] = 0;
}
void build(int &x, int l, int r, int f)
{
    if(l > r)
        return;
    int m = (l + r) >> 1;
    NewNode(x, f, m);
    build(ch[x][0], l, m-1, x);
    build(ch[x][1], m+1, r, x);
    pushup(x);
}

void init(int n)
{
	ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0;
	rev[0] = val[0] = 0;
	
	root = top1 = 0;
	NewNode(root, 0, -1);
	NewNode(ch[root][1], root, -1);
	sz[root] = 2;
	build(ch[ch[root][1]][0], 1, n, ch[root][1]);
	pushup(ch[root][1]);
	pushup(root);
	
}

int kth(int x, int k)
{
	pushdown(x);
	if(!x)
		return 0;
	int s = sz[ch[x][0]];
	if(k == s+1)
		return x;
	if(k <= s)
		return kth(ch[x][0], k);
	return kth(ch[x][1], k-s-1);
}


void update(int l, int r, int n)
{
	splay(kth(root, l), 0);
	splay(kth(root, r+2), root);
	rever(ch[ch[root][1]][0]);
	
	int temp = ch[ch[root][1]][0];
	ch[ch[root][1]][0] = 0;
	
	pushup(ch[root][1]);
	pushup(root);
	
	splay(kth(root, n+1), 0);
	int m = get_min(ch[root][1]);
	splay(m, root);
	ch[ch[root][1]][0] = temp;
	pre[ch[ch[root][1]][0]] = ch[root][1];
	pushup(ch[root][1]);
	pushup(root);
}

int get_min(int x)
{
	if(!x)
		return 0;
	while(ch[x][0])
	{
		x = ch[x][0];
	}
	return x;
}
int get_max(int x)
{
	if(!x)
		return 0;
	while(ch[x][1])
	{
		x = ch[x][1];
	}
	return x;
}
void remove()
{
	if(!ch[root][0])
	{
		root = ch[root][1];
		pre[root] = 0;
	}
	else
	{
		int m = get_max(ch[root][0]);
		splay(m, root);
		ch[m][1] = ch[root][1];
		pre[ch[root][1]] = m;
		root = m;
		pre[root] = 0;
	}
}
void insert(int x, int k, int p)
{
	if(x == 0)
	{
		NewNode(root, 0, k, p);
		return;
	}
	while(ch[x][val[x]<p])
		x = ch[x][val[x]<p];
	NewNode(ch[x][val[x]<p], x, k, p);
	splay(ch[x][val[x]<p], 0);
}

void print(int x, int n)
{
	if(!x)
		return;
	pushdown(x);
	print(ch[x][0], n);
	if(val[x] >= 1 && val[x]<= n)	
	{
		printf("%d\n", val[x]);
	}
	print(ch[x][1], n);

	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值