[UVA11922] Permutation Transformer && Splay模板

模板题 无需多说

#include<iostream>
#include<cstdio>
using namespace std;
#define MAXN 500000
#define INF 99999999
int n, m;
struct Node {
    int key, sz, cnt;
    int flag;
    Node *ch[2], *fa;
    Node(){}
    Node(int x, int y, int z) {
        key = x, sz = y, cnt = z;
    }
    void Update() {
        sz = ch[0]->sz + ch[1]->sz + cnt;
    }
    int cmp(int v) const {
        if(v == key) return -1;
        return v < key ? 0 : 1;
    }
}nil(0, 0, 0), *NIL = &nil;
struct Splay_Tree
{
    Node *root;
    int ncnt;
    Node tree[MAXN+10];
    void init() { root = NIL; ncnt = 0; }
    Node *NewNode(){
        Node &t = tree[++ncnt];
        t.ch[0] = t.ch[1] = t.fa = NIL;
        t.sz = t.cnt = 1;
        t.flag = 0;
        return &tree[ncnt];
    }
    void pushdown(Node *target) {
        if(target->flag)
        {
            target->flag = 0;
            swap(target->ch[0], target->ch[1]);
            if(target->ch[0] != NIL) target->ch[0]->flag ^= 1;
            if(target->ch[1] != NIL) target->ch[1]->flag ^= 1;
        }
    }
    void Rotate(Node *x, int d)
    {
        Node *y = x->fa;
        y->ch[!d] = x->ch[d];
        if(x->ch[d] != NIL) x->ch[d]->fa = y;
        x->fa = y->fa;
        if(y->fa != NIL) y->fa->ch[y->fa->ch[1] == y] = x;
        x->ch[d] = y;
        y->fa = x;
        if(y == root) root = x;
        y->Update();
    }
    void splay(Node *x, Node *target)
    {
        Node *y, *z;
        while(x->fa != target)
        {
            pushdown(x);
            y = x->fa;
            z = y->fa;
            if(z == target)
            {
                if(x == y->ch[0]) Rotate(x, 1);
                else Rotate(x, 0);
            }
            else
            {
                if(y == z->ch[0])
                    if(x == y->ch[0])
                        Rotate(y, 1), Rotate(x, 1);
                    else
                        Rotate(x, 0), Rotate(x, 1);
                else
                    if(x == y->ch[0])
                        Rotate(x, 1), Rotate(x, 0);
                    else
                        Rotate(y, 0), Rotate(x, 0);
            }
            x->Update();
        }
    }
    void insert(Node * &target, int val, Node *F)
    {
        if(target == NIL) {
            target = NewNode();
            target->key = val;
            target->fa = F;
            splay(target, NIL);
            return ;
        }
        int d = target->cmp(val);
        if(d == -1) {
            target->cnt++;
            target->sz++;
            target->Update();
            splay(target, NIL);
            return;
        }
        target->sz++;
        insert(target->ch[d], val, target);
    }
    Node *Find_key(Node *target, int key)
    {
        if(target == NIL) return NIL;
        if(key == target->key)
            return target;
        if(key > target->key) return Find_key(target->ch[1], key);
        else return Find_key(target->ch[0], key);
    }
    Node *Find_d(Node * &x, int d)
    {
        if(x == NIL) return x;
        while(x->ch[d] != NIL) {
            if(x->flag) pushdown(x);
            if(x->ch[d] == NIL) return x;
            x = x->ch[d];
        }
        return x;
    }
    void Del(int key)
    {
        if(root == NIL) return ;
        Node *x = Find_key(root, key);
        if(x == NIL) return ;
        if(x->cnt > 1) {
            x->cnt--;
            x->sz--;
            splay(x, NIL);
            return ;
        }
        x->sz = 0;
        while(x->ch[0] != NIL || x->ch[1] != NIL)
        {
            if(x->ch[0] != NIL) splay(x->ch[0], x->fa);
            if(x->ch[1] != NIL) splay(x->ch[1], x->fa);
        }
        if(x == root) {
            root = NIL;
            return ;
        }
        x->fa->Update();
        if(x->fa->ch[0] == x) x->fa->ch[0] = NIL;
        if(x->fa->ch[1] == x) x->fa->ch[1] = NIL;
        splay(x->fa, NIL);
    }
    int Find_rank(Node *target, const int key)
    {
        if(target == NIL) return 0;
        if(key == target->key) return target->ch[0]->sz + 1;
        if(key < target->key) return Find_rank(target->ch[0], key);
        if(key > target->key) return target->ch[0]->sz + target->cnt + Find_rank(target->ch[1], key);
        return 0;
    }
    int Find_kth(Node *target, const int k, int Left)
    {
        if(target == NIL) return -1;
        if(Left + target->ch[0]->sz >= k) return Find_kth(target->ch[0], k, Left);
        if(Left + target->cnt + target->ch[0]->sz >= k) return target->key;
        if(Left + target->ch[0]->sz + target->cnt < k) return Find_kth(target->ch[1], k, Left + target->ch[0]->sz + target->cnt);
        return -1;
    }
    Node *Find_kth_dir(Node *target, const int k, int Left = 0)
    {
        if(target == NIL) return NIL;
        if(target->flag) {
            pushdown(target);
        }
        if(Left + target->ch[0]->sz >= k) return Find_kth_dir(target->ch[0], k, Left);
        else if(Left + target->cnt + target->ch[0]->sz >= k) 
            return target;
        else if(Left + target->ch[0]->sz + target->cnt < k) return Find_kth_dir(target->ch[1], k, Left + target->ch[0]->sz + target->cnt);
        return NIL;
    }
    void Flip(Node *target) { target->flag ^= 1; }
    void Print_ans(Node *target)
    {
        if(target == NIL) return ;
        if(target->flag) pushdown(target);
        Print_ans(target->ch[0]);
        if(target->key != 0 && target->key <= n) for(int i = 1; i <= target->cnt; i++) printf("%d\n", target->key);
        Print_ans(target->ch[1]);
    }
	void split(Node *x, Node *target, Node * &Left, Node * &Right)
    {
        splay(target, NIL);
        Left = target;
        Right = target->ch[1];
        target->ch[1] = NIL;
		Right->fa = NIL;
        target->Update();
    }
    Node *merge(Node *Left, Node *Right)
    {
        splay(Left = Find_kth_dir(Left, Left->sz, 0), NIL);
        Left->ch[1] = Right;
		Right->fa = Left;
		Left->Update();
		return Left;
	}
};
Splay_Tree sp;
int main()
{
    sp.init();
    scanf("%d%d", &n, &m);
    for(int i = 0; i <= n; i++) sp.insert(sp.root, i, NIL);
    for(int i = 1; i <= m; i++)
    {
        int l, r;
        scanf("%d%d", &l, &r);
		Node *left, *right, *Mid, *tmp;
		Node *L = sp.Find_kth_dir(sp.root, l, 0);
		sp.split(sp.root, L, left, tmp);
		Node *R = sp.Find_kth_dir(tmp, r-l+1, 0);
		sp.split(tmp, R, Mid, right);
		sp.Flip(Mid);
		sp.root = sp.merge(sp.merge(left, right), Mid);
    }
	sp.Print_ans(sp.root);
}
/*
5 3 
1 3 
1 3 
1 4
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值