首页 > 其他分享 >我发现了新的平衡树???!

我发现了新的平衡树???!

时间:2022-12-30 15:12:16浏览次数:35  
标签:发现 bf return int sum cnt else 平衡

前导

这也算是 Treap 的一个变体吧。借鉴了树的重心的思想。
我把这棵树叫做 BFT,即 Brute_Force Tree,暴力树。
小蒟蒻不会高级算法,如果已经有了类似的树,请各位尽管d我。

介绍

这种新的平衡树没有随机键值,而是通过子树大小来实现平衡操作。容易发现,如果这棵树的每一个节点都是其所在子树的重心,那么这棵树的深度一定是 \(\log(n)\) 的。所以,如果以这棵树的某个节点的两个儿子为根的两棵子树中有一棵的大小大于该节点为根的子树大小的一半,那么就旋转。代码中使用了 balance() 函数来实现这种操作。
删除节点、查找前驱、后继、排名同Treap。在这些函数的末尾应当调用 balance() 来保证平衡性。

复杂度

\(n\log(n)\)。开 O2 在 LibreOJ 上跑了 100ms,洛谷 165ms。
跑起来速度和 Treap 差不多,但是更好写,更好理解。

代码

放进 LibreOJ 里格式化了一下。

#include "iostream"
using namespace std;
#define inf 100010
#define maxn 1e8
struct node {
    int l, r, v, cnt, sum;
} bf[inf];
int top, n, rt;
template<typename T>inline bool read(T &x_) {
    int x = 0, f = 1;
    char ch = getchar();

    while (ch < '0' || ch > '9') {
        if (ch == '-')
            f = -1;

        ch = getchar();
    }

    while (ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + ch - '0';
        ch = getchar();
    }

    x_ = x * f;
    return 1;
}
template<typename T, typename ...Args>inline bool read(T &a, Args &...args) {
    return read(a) && read(args...);
}
void print_(int x) {
    if (x >= 10)
        print_(x / 10);
    putchar(x % 10 + '0');
}
void print(int x) {
    if(x<0)x=-x,putchar('-');
    print_(x);
    putchar('\n');
}
void pushup(int x) {
    bf[x].sum = bf[bf[x].l].sum + bf[bf[x].r].sum + bf[x].cnt;
}
int newnode(int x) {
    bf[++top].v = x;
    bf[top].cnt = bf[top].sum = 1;
    return top;
}
void zig(int &p) { //右旋
    int q = bf[p].l;
    bf[p].l = bf[q].r, bf[q].r = p, p = q;
    pushup(bf[p].r), pushup(p);
}
void zag(int &p) { //左旋
    int q = bf[p].r;
    bf[p].r = bf[q].l;
    bf[q].l = p;
    p = q;
    pushup(bf[p].l), pushup(p);
}
void bdtree() {
    newnode(-maxn), newnode(maxn);
    rt = 1;
    bf[1].r = 2;
    pushup(rt);
}
void balance(int &p) {
    if (!p)
        return;

    pushup(p);

    if (bf[bf[p].l].sum > bf[p].sum / 2)
        zig(p);
    else if (bf[bf[p].r].sum > bf[p].sum / 2)
        zag(p);
}
void insert(int &p, int v) {
    if (p == 0)
        p = newnode(v);
    else if (bf[p].v == v)
        bf[p].cnt++;
    else if (bf[p].v > v)
        insert(bf[p].l, v);
    else
        insert(bf[p].r, v);

    balance(p);
}
void delnode(int &p, int v) {
    if (p == 0)
        return;

    if (bf[p].v == v) {
        if (bf[p].cnt > 1)
            bf[p].cnt--;
        else if (bf[p].l || bf[p].r) {
            if (!bf[p].r)
                zig(p), delnode(bf[p].r, v);
            else
                zag(p), delnode(bf[p].l, v);
        } else
            return p = 0, void();
    } else if (bf[p].v > v)
        delnode(bf[p].l, v);
    else
        delnode(bf[p].r, v);

    balance(p);
}
int getrk(int p, int v) {
    if (p == 0)
        return 0;

    if (bf[p].v == v)
        return bf[bf[p].l].sum + 1;

    if (bf[p].v > v)
        return getrk(bf[p].l, v);

    return getrk(bf[p].r, v) + bf[bf[p].l].sum + bf[p].cnt;
}
int gettg(int p, int rk) {
    if (p == 0)
        return maxn;

    if (bf[bf[p].l].sum >= rk)
        return gettg(bf[p].l, rk);

    if (bf[bf[p].l].sum + bf[p].cnt >= rk)
        return bf[p].v;

    return gettg(bf[p].r, rk - bf[bf[p].l].sum - bf[p].cnt);
}
int getpr(int p, int v) {
    if (p == 0)
        return -maxn;

    if (bf[p].v >= v)
        return getpr(bf[p].l, v);

    return max(getpr(bf[p].r, v), bf[p].v);
}
int getsu(int p, int v) {
    if (p == 0)
        return maxn;

    if (bf[p].v <= v)
        return getsu(bf[p].r, v);

    return min(getsu(bf[p].l, v), bf[p].v);
}
int main() {
    read(n);
    bdtree();

    for (int i = 1, opt, x; i <= n; i++) {
        read(opt, x);
        if (opt == 1)
            insert(rt, x);
        else if (opt == 2)
            delnode(rt, x);
        else if (opt == 3)
            print(getrk(rt, x) - 1);
        else if (opt == 4)
            print(gettg(rt, x + 1));
        else if (opt == 5)
            print(getpr(rt, x));
        else if (opt == 6)
            print(getsu(rt, x));
    }

    return 0;
}

标签:发现,bf,return,int,sum,cnt,else,平衡
From: https://www.cnblogs.com/lunatic-unleashed/p/17014908.html

相关文章

  • 想通过anconda来创建一个虚拟环境,结果发现一直报错。An unexpected error has occurre
    本来想要通过condacreate-ndrf-adminpython==3.8 来创建一个虚拟环境,结果一直报错。Anunexpectederrorhasoccurred.Condahaspreparedtheabovereport.如......
  • 掌握这5大功能,解锁鲲鹏开发新发现
    摘要:目前,鲲鹏亲和开发框架提供:场景化SDK、启发式编程、鲲鹏亲和分析、鲲鹏调试器、远程实验室等功能,降低开发应用难度,方便开发者使用鲲鹏架构提供的软硬协同能力,提升开发效......
  • 记录几个新发现的优秀CRM客户管理系统
    近期寻找CRM系统,前后试用了十几款,在这个过程中体验了一些名不符实的软件,也发现了一些优秀却不够知名的产品,特此记录几个以作备忘。 蓝点客户关系管理系统知名度不高,但......
  • 从发现SQL注入到ssh连接
    前言:某天,同事扔了一个教育站点过来,里面的url看起来像有SQL注入。正好最近手痒痒,就直接开始。一、发现时间盲注和源码后面发现他发的url是不存在SQL注入的,但是我在其他地......
  • 后缀平衡树
    继续搞点字符串。后缀平衡树。后缀平衡树,就是后缀数组上平衡树。它的中序遍历是后缀数组。但是它可以在线\(O(n\logn)\)构建,虽然码量大点。当然你可以先把后缀数组求......
  • 什么?Coolbpf 不仅可以远程编译,还可以发现网络抖动! | 龙蜥技术
    近日,在 ​​2022云栖大会龙蜥峰会eBPF&Linux稳定性专场​​上,来自eBPF技术探索SIGMaintainer的毛文安分享了《Coolbpf的应用实践》技术演讲,以下为本次演讲内容:......
  • 平衡树
    fhq-treap对于一个集合,需要维护它,我们考虑一个包含集合中所有元素的有序序列,并使用一棵树,其中每一个子树都对应着一个子序列:这棵树有什么性质呢?首先它是一棵二叉查找树,......
  • 平衡树
    平衡树包括很多种类,常见的有B树、AVL树、红黑树等。这些树都大致平衡,能保证最坏情况下为O(logN)的性能,因此广受大家的欢迎。但是由于平衡机制的不同,这些树都有着不同的应......
  • P3369普通平衡树 学习笔记
    题意写一棵平衡树,需要实现如下几种操作:插入\(x\)数删除\(x\)数(若有多个相同的数,因只删除一个)查询\(x\)数的排名(排名定义为比当前数小的数的个数\(+1\))查......
  • 嘤嘤的新平衡树
    给定一棵二叉树,二叉树的每个结点只有0或2个孩子。你需要对每个结点赋值一个正整数,使得每个结点的左右子树权值和相等。你需要返回所有结点的最小权值和对109+7取模的结......