zoukankan      html  css  js  c++  java
  • BZOJ 3224 JoyOI 1728 普通平衡树

    treap板子(搬运黄学长)附黄学长传送门

    「BZOJ3224」JoyOI 1728 普通平衡树 - treap - hzwer.com

    treap具有了heap的性质也具有一般平衡树的性质,它满足二叉查找树的性质,然后满足heap的优先级

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    struct data{
        int l,r,v,sz,rnd,w;//l==lson r==rson v==val sz==size w==this node num   rnd== baout heap
    }tr[100005];
    int n,sz,root,ans;
    void update(int k)//更新结点信息
    {
        tr[k].sz=tr[tr[k].l].sz + tr[tr[k].r].sz + tr[k].w;
    }
    void rturn(int &k)
    {
        int t=tr[k].l;
        tr[k].l=tr[t].r;
        tr[t].r=k;
        tr[t].sz=tr[k].sz;
        update(k);
        k=t;
    }
    
    void lturn(int &k)
    {
        int t=tr[k].r;
        tr[k].r=tr[t].l;
        tr[t].l=k;
        tr[t].sz=tr[k].sz;
        update(k);
        k=t;
    }
    
    void Insert(int &k,int x)
    {
        if(k==0){
            sz++;k=sz;
            tr[k].sz=tr[k].w=1;
            tr[k].v=x;
            tr[k].rnd=rand();
            return;
        }
        tr[k].sz++;
        if(tr[k].v==x)tr[k].w++;//每个结点顺便记录下与该节点相同值的数的个数
        else if(x>tr[k].v){
            Insert(tr[k].r,x);
            if(tr[tr[k].r].rnd<tr[k].rnd)lturn(k);//维护堆性质
        }
        else{
            Insert(tr[k].l,x);
            if(tr[tr[k].l].rnd<tr[k].rnd)rturn(k);
        }
    }
    void del(int &k,int x)
    {
        if(k==0)return;
        if(tr[k].v==x){
            if(tr[k].w>1){
                tr[k].w--;tr[k].sz--;return;//若不止相同值的个数有多个,删去一个
            }
            if(tr[k].l*tr[k].r==0)k=tr[k].l+tr[k].r;//有一个儿子为空
            else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd)
                rturn(k),del(k,x);
            else lturn(k),del(k,x);
        }
        else if(x>tr[k].v)
            tr[k].sz--,del(tr[k].r,x);
        else tr[k].sz--,del(tr[k].l,x);
    }
    
    int query_rank(int k,int x)
    {
        if(k==0)return 0;
        if(tr[k].v==x)return tr[tr[k].l].sz+1;
        else if(x>tr[k].v)
            return tr[tr[k].l].sz+tr[k].w+query_rank(tr[k].r,x);
        else return query_rank(tr[k].l,x);
    }
    
    int query_num(int k,int x)
    {
        if(k==0)return 0;
        if(x<=tr[tr[k].l].sz)
            return query_num(tr[k].l,x);
        else if(x>tr[tr[k].l].sz+tr[k].w)
            return query_num(tr[k].r,x-tr[tr[k].l].sz-tr[k].w);
        else return tr[k].v;
    }
    
    void query_pro(int k,int x)
    {
        if(k==0)return;
        if(tr[k].v<x){
            ans=k;query_pro(tr[k].r,x);
        }
        else query_pro(tr[k].l,x);
    }
    
    void query_sub(int k,int x)
    {
        if(k==0)return;
        if(tr[k].v>x){
            ans=k;query_sub(tr[k].l,x);
        }
        else query_sub(tr[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
    ",query_rank(root,x));break;
                case 4:printf("%d
    ",query_num(root,x));break;
                case 5:ans=0;query_pro(root,x);printf("%d
    ",tr[ans].v);break;
                case 6:ans=0;query_sub(root,x);printf("%d
    ",tr[ans].v);break;
            }
        }
        return 0;
    }
  • 相关阅读:
    org.dom4j.DocumentException: null Nested exception: null
    严重: 文档无效: 找不到语法。 at (null:2:19)
    微信 群好友 的返回微信号 有阉割
    Perl 面向对象的真正意思
    门外汉怎么成就咨询大单(1)——北漂18年(39)
    Perl 微信模块--Weixin::Client
    Solr使用入门指南
    Perl 对象是函数的第一个参数
    haproxy 4层负载
    mysql 从读负载
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/9112607.html
Copyright © 2011-2022 走看看