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

平衡树板子qaq

时间:2018-09-03 20:27:12      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:分享图片   color   lld   img   gif   sign   next   print   define   

bzoj3224

技术分享图片
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 100005
#define inf 0x7ffffffffffff
#define int long long
struct treap
{
    int l,r,val,dat,cnt,size;
}a[N];
int tot=0,root,n;
inline int New(int val)
{
    a[++tot].val=val; a[tot].dat=rand(); a[tot].cnt=a[tot].size=1; return tot;
}
inline void updata(int p)
{
    a[p].size=a[a[p].l].size+a[a[p].r].size+a[p].cnt;
}
inline void build()
{
    New(-inf); New(inf);
    root=1; a[1].r=2; updata(root);
}
inline int GetRankByVal(int p,int val)
{
    if(p==0) return 0;
    if(val==a[p].val) return a[a[p].l].size+1;
    if(val<a[p].val) return GetRankByVal(a[p].l,val);
    return GetRankByVal(a[p].r,val)+a[a[p].l].size+a[p].cnt;
}
inline int GetValByRank(int p,int rank)
{
    if(p==0) return inf;
    if(a[a[p].l].size>=rank) return GetValByRank(a[p].l,rank);
    if(a[a[p].l].size+a[p].cnt>=rank) return a[p].val;
    return GetValByRank(a[p].r,rank-a[a[p].l].size-a[p].cnt);
}
inline void rturn(int &p)
{
    int q=a[p].l;
    a[p].l=a[q].r; a[q].r=p; p=q;
    updata(a[q].r); updata(p);
}
inline void lturn(int &p)
{
    int q=a[p].r;
    a[p].r=a[q].l; a[q].l=p; p=q;
    updata(a[q].l); updata(p);
}
inline void insert(int &x,int val)
{
    if(x==0)
    {
        x=New(val); return;
    }
    if(val==a[x].val)
    {
        a[x].cnt++; updata(x); return;
    }
    if(val<a[x].val)
    {
        insert(a[x].l,val); if(a[x].dat<a[a[x].l].dat) rturn(x);
    }
    else
    {
        insert(a[x].r,val); if(a[x].dat<a[a[x].r].dat) lturn(x);
    }
    updata(x);
}
inline int GetPre(int val)
{
    int ans=1,p=root;
    while(p)
    {
        if(val==a[p].val)
        {
            if(a[p].l>0)
            {
                p=a[p].l; while(a[p].r>0)p=a[p].r; ans=p;
            }
            break;
        }
        if(a[p].val<val&&a[p].val>a[ans].val) ans=p;
        p=val<a[p].val?a[p].l:a[p].r;
    }
    return a[ans].val;
}
inline int GetNext(int val)
{
    int ans=2,p=root;
    while(p)
    {
        if(val==a[p].val)
        {
            if(a[p].r>0)
            {
                p=a[p].r; while(a[p].l>0)p=a[p].l; ans=p;
            }
            break;
        }
        if(a[p].val>val&&a[p].val<a[ans].val) ans=p;
        p=val<a[p].val?a[p].l:a[p].r;
    }
    return a[ans].val;
}
inline void remove(int &p,int val)
{
    if(p==0)return;
    if(val==a[p].val)
    {
        if(a[p].cnt>1)
        {
            a[p].cnt--; updata(p); return;
        }
        if(a[p].l||a[p].r)
        {
            if(a[p].r==0||a[a[p].l].dat>a[a[p].r].dat)
            {
                rturn(p); remove(a[p].r,val);
            }
            else
            {
                lturn(p); remove(a[p].l,val);
            }
            updata(p);
        }
        else p=0;
        return;
    }
    val<a[p].val?remove(a[p].l,val):remove(a[p].r,val);
    updata(p);
}
signed main()
{
    int i,op,x; build(); scanf("%lld",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%lld%lld",&op,&x);
        switch(op)
        {
            case 1: insert(root,x); break;
            case 2: remove(root,x); break;
            case 3: printf("%d\n",GetRankByVal(root,x)-1); break;
            case 4: printf("%d\n",GetValByRank(root,x+1)); break;
            case 5: printf("%d\n",GetPre(x)); break;
            case 6: printf("%d\n",GetNext(x)); break;
        }
    }
}
View Code

 

平衡树板子qaq

标签:分享图片   color   lld   img   gif   sign   next   print   define   

原文地址:https://www.cnblogs.com/gaojunonly1/p/9580552.html

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