BZOJ-3224 Tyvj 1728 普通平衡树

3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 20192 Solved: 8907
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]
Source

题解
可以写Treap,也可以写spaly。

如果在洛谷里评测发现最后一个点过不去,很可能是因为INF开小了或者是没考虑负数。

代码
Treap(C++)

#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+5,M=10000000,INF=((long long)1<<31)-1;
int n,siz=1;
int Ran(int x){return (rand()<<16|rand()<<1|(rand()&1))%x;}
struct nod{
    //w表示点的值,s表示个点的数,tem表示子树上的节点树,id表示优先级
    //son表示儿子节点,sum表示下一个新节点的号码(已经诞生了的节点个数) 
    int w,s,tem,id,son[2];
    void giv(int t1,int t2,int t3,int t4,int t5,int t6)
    {
        w=t1;s=t2;tem=t3;id=t4;son[0]=t5;son[1]=t6;
    }
}a[maxn];
int Bmin(int x,int y){return a[x].w<a[y].w? x:y;}
//修正子节点个数 
void Updata(int x){a[x].tem=a[x].s+a[a[x].son[0]].tem+a[a[x].son[1]].tem;}
//旋转,p=0/1表示左转/右转 
void Rotat(int &x,int p)
{
    int y=a[x].son[p^1];
    a[x].son[p^1]=a[y].son[p];
    a[y].son[p]=x;
    a[y].tem=a[x].tem;
    Updata(x);x=y;
}
//插入一个节点
void Insert(int &x,int num)
{
    if (!x){x=++siz;a[x].giv(num,1,1,Ran(M),0,0);return;}
    a[x].tem++;
    if (num<a[x].w)
    {
        Insert(a[x].son[0],num);
        if (a[x].id>a[a[x].son[0]].id) Rotat(x,1);
    }else
    if (num>a[x].w)
    {
        Insert(a[x].son[1],num);
        if (a[x].id>a[a[x].son[1]].id) Rotat(x,0);
    }else a[x].s++;
}
void del(int &x,int num)
{
    if (!x) return;
    if (num<a[x].w) a[x].tem--,del(a[x].son[0],num);else
    if (num>a[x].w) a[x].tem--,del(a[x].son[1],num);else
    if (a[x].w==num)
    {
        if (a[x].s>1) {a[x].s--;a[x].tem--;return;}
        if (a[x].son[0]&&a[x].son[1])
        {
            if (a[a[x].son[0]].id<a[a[x].son[1]].id) Rotat(x,1),del(x,num);
                                                else Rotat(x,0),del(x,num);
        }else x=a[x].son[0]+a[x].son[1];
    }
}
int query_paimi(int x,int num)
{
    if (!x) return 0;
    if (a[x].w==num) return a[a[x].son[0]].tem+1;else
    if (a[x].w>num) return query_paimi(a[x].son[0],num);else
    return a[a[x].son[0]].tem+a[x].s+query_paimi(a[x].son[1],num);
}
int query_dinmin(int x,int num)
{
    if (!x) return 0;
    if (num<=a[a[x].son[0]].tem) return query_dinmin(a[x].son[0],num);else
    if (num>a[a[x].son[0]].tem+a[x].s) return query_dinmin(a[x].son[1],num-a[a[x].son[0]].tem-a[x].s);else
    return a[x].w;
}
int query_qianq(int x,int num)
{
    if (!x) return -INF;
    if (num>a[x].w) return max(a[x].w,query_qianq(a[x].son[1],num));
    else return query_qianq(a[x].son[0],num);
}
int query_houji(int x,int num)
{
    if (!x) return INF;
    if (num<a[x].w) return min(a[x].w,query_houji(a[x].son[0],num));
    else return query_houji(a[x].son[1],num);
}
int Read()
{
    int ret=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
    return ret*f;
}
int main()
{
    srand((unsigned)time(0));
    n=Read();int pd,x,rot=0;
    for (int i=1;i<=n;i++)
    {
        pd=Read();x=Read();
        switch(pd)
        {
            case 1:{Insert(rot,x);break;}
            case 2:{del(rot,x);break;}
            case 3:{printf("%d\n",query_paimi(rot,x));break;}
            case 4:{printf("%d\n",query_dinmin(rot,x));break;}
            case 5:{printf("%d\n",query_qianq(rot,x));break;}
            case 6:{printf("%d\n",query_houji(rot,x));break;}
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xu0_zy/article/details/80083106
今日推荐