码迷,mamicode.com
首页 > 其他好文 > 详细

Treap模板

时间:2018-05-01 23:48:42      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:定义   targe   www   names   main   str   模板   show   include   

题目:https://www.luogu.org/problemnew/show/P3369

Treap模板。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const MAXN=100005,inf=1e9;
int n,rt,cnt;
struct N{
    int ch[3],val,siz,pri,num;
}t[MAXN];
int newnode()
{
    int r=++cnt;
    t[r].siz=1;t[r].num=1;t[r].pri=rand();
    return r;
}
void pushup(int &o)
{
    t[o].siz=t[t[o].ch[0]].siz+t[t[o].ch[1]].siz+t[o].num;
}
void rotate(int &o,int d)
{
    int u=t[o].ch[d];
    t[o].ch[d]=t[u].ch[d^1];
    t[u].ch[d^1]=o;
    t[u].siz=t[o].siz;
    pushup(o);
    o=u;
}
void add(int &o,int x)
{
    if(!o)
    {
        o=newnode();
        t[o].val=x;
        return;
    }
    if(t[o].val==x)
    {
        t[o].num++;t[o].siz++;
        return;
    }
    int d=t[o].val<x;
    add(t[o].ch[d],x);
    pushup(o);
    if(t[t[o].ch[d]].pri<t[o].pri)rotate(o,d);
}
void del(int &o,int x)
{
    if(!o)return;
    if(t[o].val==x)
    {
        if(t[o].num>1)t[o].num--;
        else if(t[o].ch[1]*t[o].ch[0]==0)//
            o=t[o].ch[1]+t[o].ch[0];
        else
        {
            int d=t[t[o].ch[0]].pri<t[t[o].ch[1]].pri;
            rotate(o,d^1);
            del(o,x);//o!
        }
        pushup(o);
        return;
    }
    int d=t[o].val<x;
    del(t[o].ch[d],x);
    pushup(o);
}
int query(int &o,int x)
{
    if(!o)return 0;
    if(t[o].val==x)return t[t[o].ch[0]].siz+1;
    int d=t[o].val<x;
    if(!d)return query(t[o].ch[d],x);
    return query(t[o].ch[d],x)+t[o].num+t[t[o].ch[0]].siz;
}
int qr(int &o,int x)
{
    if(!o||!x)return 0;
    int d=x-t[t[o].ch[0]].siz;
    if(d<=0)return qr(t[o].ch[0],x);
    if(d<=t[o].num)return t[o].val;
    return qr(t[o].ch[1],x-t[t[o].ch[0]].siz-t[o].num);
}
int pre(int &o,int x)
{
    if(!o)return -inf;//
    if(t[o].val<x)return max(t[o].val,pre(t[o].ch[1],x));
    return pre(t[o].ch[0],x);
}
int lst(int &o,int x)
{
    if(!o)return inf;//
    if(t[o].val>x)return min(t[o].val,lst(t[o].ch[0],x));
    return lst(t[o].ch[1],x);
}
int main()
{
    scanf("%d",&n);
    for(int i=1,x,opt;i<=n;i++)
    {
        scanf("%d%d",&opt,&x);
        if(opt==1)add(rt,x);//插入 x 数
        if(opt==2)del(rt,x);//删除 x 数(若有多个相同的数,只删除一个)
        if(opt==3)printf("%d\n",query(rt,x));
        //查询 x 数的排名(排名定义为比当前数小的数的个数 +1,若有多个相同的数,输出最小的排名)
        if(opt==4)printf("%d\n",qr(rt,x));//查询排名为 x 的数
        if(opt==5)printf("%d\n",pre(rt,x));//求 x 的前驱(前驱定义为小于 x ,且最大的数)
        if(opt==6)printf("%d\n",lst(rt,x));//求 x 的后继(后继定义为大于 x ,且最小的数)
    }
    return 0;
}

Treap模板

标签:定义   targe   www   names   main   str   模板   show   include   

原文地址:https://www.cnblogs.com/Zinn/p/8977008.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!