Rank-Tree带动态查询删除 Splay

来源:互联网 发布:淘宝会员名字大全 编辑:程序博客网 时间:2024/05/29 09:03
#include <bits/stdc++.h>using namespace std;#define REP(i, a, b) for (int i = (a), _end_ = (b); i <= _end_; ++i)#define debug(...) fprintf(stderr, __VA_ARGS__)#define mp make_pair#define x first#define y second#define pb push_back#define SZ(x) (int((x).size()))#define ALL(x) (x).begin(), (x).end()template<typename T> inline bool chkmin(T &a, const T &b){ return a > b ? a = b, 1 : 0; }template<typename T> inline bool chkmax(T &a, const T &b){ return a < b ? a = b, 1 : 0; }typedef long long LL;const int dmax = 300100, oo = 0x3f3f3f3f;int n, m;#define L ch[0]#define R ch[1]struct node{    int x, size;    node *f, *ch[2];    node()    {        x = size = 0;        f = L = R = NULL;    }};node *Null = new node;inline node *new_node(int k){    node *tmp = new node;    tmp->x = k;    tmp->f = tmp->L = tmp->R = Null;    return tmp;}struct Splay{    node *root;    inline bool is_root(node *t){ return t->f == Null; }    inline int size(node *t){ return t == Null ? 0 : t->size; }    inline void push_up(node *t) { t->size = size(t->L) + size(t->R) + 1; }    inline void rotate(node *x)    {        node *y = x->f;        if (is_root(y))            root = x;        else{            if (y == y->f->L)                y->f->L = x;            else y->f->R = x;        }        x->f = y->f;        int k = x == y->R;        y->ch[k] = x->ch[!k];        x->ch[!k]->f = y;        x->ch[!k] = y;        y->f = x;        push_up(y);        push_up(x);    }    inline void splay(node *x, node *t)    {        while (x->f != t)        {            node *y = x->f;            if (y->f == t)                rotate(x);            else{                node *z = y->f;                if (x == z->L->L || x == z->R->R)                    rotate(y);                else rotate(x);                rotate(x);            }        }    }    inline void push(node *t, int k)    {        int T = k >= t->x;        t->ch[T] = new_node(k);        t->ch[T]->f = t;        t = t->ch[T];        node *tmp = t->f;        while (tmp != Null)        {            push_up(tmp);            tmp = tmp->f;        }        splay(t, Null);    }    void insert(int k, node *t)    {        if (root == NULL)        {            root = new_node(k);            return;        }        int T = k >= t->x;        if (t->ch[T] != Null)            insert(k, t->ch[T]);        else push(t, k);    }    int find(int k, node *t)    {        if (k == size(t->L) + 1)        {            splay(t, Null);            return t->x;        }        int T = k > size(t->L);        return find(T ? k - size(t->L) - 1 : k, t->ch[T]);    }    void del(int k, node *t)    {        if (k == t->x)        {            splay(t, Null);            node *x = t->L, *y = t->R;            x->f = y->f = Null;            delete t;            while (x->R != Null)                x = x->R;            splay(x, Null);            x->R = y;            y->f = x;            push_up(x);        }        int T = k >= t->x;        if (t->ch[T] == Null) return;        del(k, t->ch[T]);    }    Splay(){ root = NULL; }}t;int main(){#ifndef ONLINE_JUDGE    freopen("input.txt", "r", stdin);    freopen("output.txt", "w", stdout);#endif    scanf("%d%d", &n, &m);    REP(i, 1, n)    {        int k;        scanf("%d", &k);        t.insert(k, t.root);    }    getchar();    while (m--)    {        int c = getchar(), k;        scanf("%d", &k);        if (c == 'Q')            printf("%d\n", t.find(k, t.root));        else t.del(k, t.root);        getchar();    }    return 0;}
0 0