• [luogu3369]普通平衡树(替罪羊树模板)


    解题关键:由于需要根据平衡进行重建,所以不能进行去重,否则无法保证平衡性。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<iostream>
    #include<cmath>
    #include<vector>
    using namespace std;
    typedef long long ll;
    
    const double alpha=0.7;
    const int N=1e5+500;
    int n;
    
    namespace ScapegoatTree{
        struct node{
            int l,r,v,sz,valid;
            bool del;
        }t[N<<2];
        int tot=0,rt=0;
    #define ls(o) t[o].l
    #define rs(o) t[o].r
    #define pb push_back
        int new_node(int x){++tot;t[tot].l=t[tot].r=0;t[tot].v=x;t[tot].sz=t[tot].valid=1;t[tot].del=0;return tot;}
        bool Bad(int o){
            return (double)t[ls(o)].sz>alpha*t[o].sz||(double)t[rs(o)].sz>alpha*t[o].sz;
        }
        void Updata(int o){
            t[o].sz=t[ls(o)].sz+t[rs(o)].sz+1;
            t[o].valid=t[ls(o)].valid+t[rs(o)].valid+!t[o].del;
        }
        void Dfs(int o,std::vector<int> &v){
            if(!o) return;
            Dfs(ls(o),v);
            if(!t[o].del) v.pb(o);
            Dfs(rs(o),v);
        }
        int Build(std::vector<int> &v,int l,int r){
            if(l>r) return 0;//原因是右边界不包含
            int mid=(l+r)>>1,o=v[mid];
            ls(o)=Build(v,l,mid-1);
            rs(o)=Build(v,mid+1,r);
            Updata(o);
            return o;
        }
        void ReBuild(int &o){
            std::vector<int>v;
            Dfs(o,v);
            o=Build(v,0,(int)v.size()-1);
        }
        void Insert(int x,int &o){
            if(!o){
                o=new_node(x);
                return ;
            }
            if(x>=t[o].v) Insert(x,rs(o));
            else Insert(x,ls(o));
            Updata(o);
            if(Bad(o)) ReBuild(o);
            return;
        }
        //del with rnk
        void Delete(int o,int Rnk){
            if(!t[o].del&&Rnk==t[ls(o)].valid+1) {
                t[o].del=1;
                --t[o].valid;
                return;
            }
            if(Rnk<=t[ls(o)].valid+!t[o].del) Delete(ls(o),Rnk);
            else Delete(rs(o),Rnk-t[ls(o)].valid-!t[o].del);
            Updata(o);
        }
        int GetRank(int o,int x){
            int ans=1;
            while(o){
                if(t[o].v>=x) o=ls(o);
                else{
                    ans+=t[ls(o)].valid+!t[o].del;
                    o=rs(o);
                }
            }
            return ans;
        }
        int FindKth(int o,int x) {
            while(o){
                if(!t[o].del&&t[ls(o)].valid+1==x) {return t[o].v;}
                if(t[ls(o)].valid>=x) o=ls(o);
                else {
                    x-=t[ls(o)].valid+!t[o].del;
                    o=rs(o);
                }
            }
        }
        int GetPred(int o,int x){
            return FindKth(o,GetRank(o,x)-1);
        }
        int GetSucc(int o,int x){
            return FindKth(o,GetRank(o,x+1));
        }
    }
    using namespace ScapegoatTree;
    
    int main() {
        scanf("%d",&n);
        rt=0;
        while(n--) {
            int op,x;
            scanf("%d%d",&op,&x);
            if(op==1) Insert(x,rt);
            if(op==2) Delete(rt,GetRank(rt,x));
            if(op==3) printf("%d
    ",GetRank(rt,x));
            if(op==4) printf("%d
    ",FindKth(rt,x));
            if(op==5) printf("%d
    ",GetPred(rt,x));
            if(op==6) printf("%d
    ",GetSucc(rt,x));
        }
        return 0;
    }
  • 相关阅读:
    T-SQL取时间的不同方法
    JavaScript获取地址栏中的参数值并存入一个对象
    jquery.ocupload上传文件到指定目录
    Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(三)
    Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(二)
    Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(一)
    Python2.x和3.x主要差异总结
    python学习视频整理
    Django-Rest-Framework 教程: 快速入门
    Django RESTful API 设计指南
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/10375214.html
Copyright © 2020-2023  润新知