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

【bzoj3224】普通平衡树——treap

时间:2017-06-02 23:00:22      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:struct   get   str   std   clu   else   for   namespace   update   

我的第一道treap题目,treap的模版题。

代码是对着hzw的敲的,一边敲一边理解。。。

主要是熟悉一下treap的各种基本操作,详细细节看代码。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;
struct point
{
    int l,r,v,rnd,size,w;
}tree[100005];
int n,size=0,root=0,ans;
void update(int k)
{
    tree[k].size=tree[tree[k].l].size+tree[tree[k].r].size+tree[k].w;
}
void rturn(int &t)
{
    int k=tree[t].l;
    tree[t].l=tree[k].r;
    tree[k].r=t;
    tree[k].size=tree[t].size;
    update(t);
    t=k;
}
void lturn(int &t)
{
    int k=tree[t].r;
    tree[t].r=tree[k].l;
    tree[k].l=t;
    tree[k].size=tree[t].size;
    update(t);
    t=k;
}
void insert(int &k,int x)
{
    if(k==0)
    {
        size++;k=size;
        tree[k].size=tree[k].w=1;tree[k].v=x;tree[k].rnd=rand();
        return;
    }
    tree[k].size++;
    if(tree[k].v==x)tree[k].w++;
    else if(x>tree[k].v)
    {
        insert(tree[k].r,x);
        if(tree[tree[k].r].rnd<tree[k].rnd)lturn(k);
    }
    else 
    {
        insert(tree[k].l,x);
        if(tree[tree[k].l].rnd<tree[k].rnd)rturn(k);
    }
}
void del(int &k,int x)
{
    if(k==0)return ;
    if(tree[k].v==x){
        if(tree[k].w>1){
            tree[k].w--;tree[k].size--;return;
        }
        if(tree[k].l*tree[k].r==0)k=tree[k].l+tree[k].r;
        else if(tree[tree[k].l].rnd<tree[tree[k].r].rnd)rturn(k),del(k,x);
        else lturn(k),del(k,x);
    }
    else if(x>tree[k].v)
        tree[k].size--,del(tree[k].r,x);
    else tree[k].size--,del(tree[k].l,x);
}
int get_rank(int k,int x)
{
    if(k==0)return 0;
    if(tree[k].v==x)return tree[tree[k].l].size+1;
    else if(tree[k].v<x)return tree[tree[k].l].size+tree[k].w+get_rank(tree[k].r,x);
    else return get_rank(tree[k].l,x);
}
int get_x(int k,int x)
{
    if(k==0)return 0;
    if(x<=tree[tree[k].l].size)return get_x(tree[k].l,x);
    else if(x>tree[tree[k].l].size+tree[k].w)return get_x(tree[k].r,x-tree[tree[k].l].size-tree[k].w);
    else return tree[k].v;
}
void get_big(int k,int x)
{
    if(k==0)return;
    if(tree[k].v<x)
    {
        ans=k;get_big(tree[k].r,x);
    }
    else get_big(tree[k].l,x);
}
void get_small(int k,int x)
{
    if(k==0)return ;
    if(tree[k].v>x)
    {
        ans=k;get_small(tree[k].l,x);
    }
    else get_small(tree[k].r,x);
}
int main()
{
    scanf("%d",&n);
    int opt,x;
    for(int i=1;i<=n;i++)
    {
        scanf("%d %d",&opt,&x);
        switch(opt)
        {
            case 1:insert(root,x);break;
            case 2:del(root,x);break;
            case 3:printf("%d\n",get_rank(root,x));break;
            case 4:printf("%d\n",get_x(root,x));break;
            case 5:ans=0;get_big(root,x);printf("%d\n",tree[ans].v);break;
            case 6:ans=0;get_small(root,x);printf("%d\n",tree[ans].v);break;
        }
    }
    return 0;
}

万分感谢黄学长啊啊啊啊

【bzoj3224】普通平衡树——treap

标签:struct   get   str   std   clu   else   for   namespace   update   

原文地址:http://www.cnblogs.com/JKAI/p/6935265.html

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