BZOJ 3224: Tyvj 1728 普通平衡树

来源:互联网 发布:冰与火之歌第八季 知乎 编辑:程序博客网 时间:2024/06/10 14:38

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10

1 106465

4 1

1 317721

1 460929

1 644985

1 84185

1 89851

6 81968

1 492737

5 493598

Sample Output

106465

84185

492737

HINT

1.n的数据范围:n<=100000

2.每个数的数据范围:[-2e9,2e9]

分析

就是学splay模板而已,但我感觉常数好大,之后慢慢改改

代码

#include <bits/stdc++.h>#define N 500000struct{    int fa;    int son[3];    int size[3];    int count;    int cover;}t[N];int n;int node;int root;void rotate(int x,int w){    int f = t[x].fa;    int g = t[f].fa;    t[f].son[3 - w] = t[x].son[w];    if (t[x].son[w])        t[t[x].son[w]].fa = f;    t[x].fa = g;    t[f].size[3 - w] = t[x].size[w];    t[x].size[w] += t[f].size[w] + 1;    if (g)    {        if (f == t[g].son[1])            t[g].son[1] = x;        else t[g].son[2] = x;    }    t[f].fa = x;    t[x].son[w] = f;}void splay(int x){    int y;    while (t[x].fa)    {        y = t[x].fa;        if (!t[y].fa)        {            if (x == t[y].son[1])                rotate(x,2);            else rotate(x,1);            continue;        }        if (y == t[t[y].fa].son[1])        {            if (x == t[y].son[1])                rotate(y,2), rotate(x,2);            else rotate(x,1), rotate(x,2);        }        else        {            if (x == t[y].son[2])                rotate(y,1), rotate(x,1);            else rotate(x,2), rotate(x,1);        }    }    root = x;}void insert(int x,int add){    if (t[x].cover >= add)    {        if (!t[x].son[1])        {            t[x].son[1] = ++node;            t[node].cover = add;            t[node].fa = x;            if (!root)                root = node;        }        else insert(t[x].son[1],add);        t[x].size[1]++;    }    else    {        if (!t[x].son[2])        {            t[x].son[2] = ++node;            t[node].cover = add;            t[node].fa = x;            if (!root)                root = node;        }        else insert(t[x].son[2],add);        t[x].size[2]++;    }}void del(int x,int dec){    if (!x)        return;    if (dec == t[x].cover)    {        splay(x);        if (!t[x].son[1] && !t[x].son[2])        {            root = 0;            return;        }        if (!t[x].son[1])        {            root = t[x].son[2];            t[t[x].son[2]].fa = 0;            return;        }        if (!t[x].son[2])        {            root = t[x].son[1];            t[t[x].son[1]].fa = 0;            return;        }        int f = t[x].son[1];        int tmp = t[x].son[2];        while (t[f].son[2])            f = t[f].son[2];        splay(f);        t[f].son[2] = tmp;        t[tmp].fa = f;        return;    }    if (dec < t[x].cover)        del(t[x].son[1],dec);    else del(t[x].son[2],dec);}int kth(int x,int add,int now){    insert(root,add);    splay(node);    int ans = t[node].size[1] + 1;    del(node,add);    return ans;}int findK(int x,int k){    if (k == t[x].size[1] + 1)        return t[x].cover;    if (k <= t[x].size[1])        return findK(t[x].son[1],k);    else return findK(t[x].son[2],k - t[x].size[1] - 1);}bool flag;int pred(int x,int k){    int f = t[x].son[1];    if (!f)        return 0;    while (t[f].son[2])        f = t[f].son[2];    if (t[f].cover != k)        flag = 1;    return f;}int succ(int x,int k){    int f = t[x].son[2];    if (!f)        return 0;    while (t[f].son[1])        f = t[f].son[1];    if (t[f].cover != k)        flag = 1;    return f;}int main(){    int n;    scanf("%d",&n);    for (int i = 1; i <= n; i++)    {        int opt,x;        scanf("%d%d",&opt,&x);        if (opt == 1)            insert(root,x), splay(node);        if (opt == 2)            del(root,x);        if (opt == 3)            printf("%d\n",kth(root,x,0));        if (opt == 4)            printf("%d\n",findK(root,x));        if (opt == 5)        {            int ans;            insert(root,x);            splay(node);            for (flag = 0, ans = pred(root,x); !flag || !ans; splay(ans), ans = pred(root,x));            del(root,x);            printf("%d\n",t[ans].cover);        }        if (opt == 6)        {            int ans;            insert(root,x);            splay(node);            for (flag = 0, ans = succ(root,x); !flag || !ans; splay(ans), ans = succ(root,x));            del(root,x);            printf("%d\n",t[ans].cover);        }    }}
0 0