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

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

时间:2019-02-14 16:29:17      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:mes   iostream   pre   std   ios   get   define   algorithm   include   

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

#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;
        void New(int x) {l=r=0;v=x;sz=valid=1;del=0;}
    }t[N<<2];
#define ls(o) t[o].l
#define rs(o) t[o].r
#define pb push_back
    int tot=0,rt=0;
    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;
        int o=v[mid];
        ls(o)=Build(v,l,mid);
        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());
    }
    void Insert(int x,int &o) {
        if(!o){
            o=++tot;
            t[o].New(x);
            return ;
        }
        t[o].sz++;t[o].valid++;
        if(x>=t[o].v) Insert(x,rs(o));
        else Insert(x,ls(o));
        if(Bad(o)) ReBuild(o);
        return ;
    }
    void Delete(int o,int Rnk) {
        if(!t[o].del&&Rnk==t[ls(o)].valid+1) {
            t[o].del=1;
            --t[o].valid;
            return ;
        }
        --t[o].valid;
        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);
    }
    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);
            }
        }
    }
}
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\n",GetRank(rt,x));
        if(op==4) printf("%d\n",FindKth(rt,x));
        if(op==5) printf("%d\n",FindKth(rt,GetRank(rt,x)-1));
        if(op==6) printf("%d\n",FindKth(rt,GetRank(rt,x+1)));
    }
    return 0;
}

 

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

标签:mes   iostream   pre   std   ios   get   define   algorithm   include   

原文地址:https://www.cnblogs.com/elpsycongroo/p/10375214.html

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