首页 > 其他分享 >平衡二叉树板子(转载)

平衡二叉树板子(转载)

时间:2022-10-06 20:11:25浏览次数:49  
标签:ch cur val int 板子 fa 二叉树 转载 root

#include <iostream>
#include <cstdio>
#define MAXN 100010
using namespace std;
int root, tot;
struct Splay
{
    int fa;
    int ch[2];
    int val;
    int cnt;
    int size;
} t[MAXN];
void maintain(int x)
{
    t[x].size = t[t[x].ch[0]].size + t[t[x].ch[1]].size + t[x].cnt;
}
bool get(int x)
{
    return x == t[t[x].fa].ch[1];
}
void clear(int x)
{
    t[x].ch[0] = t[x].ch[1] = t[x].fa = t[x].val = t[x].cnt = t[x].size = 0;
}
void rotate(int x)
{
    int y = t[x].fa, z = t[y].fa, chk = get(x);
    t[y].ch[chk] = t[x].ch[chk ^ 1];
    if (t[x].ch[chk ^ 1])
        t[t[x].ch[chk ^ 1]].fa = y;
    t[x].ch[chk ^ 1] = y;
    t[y].fa = x;
    t[x].fa = z;
    if (z)
        t[z].ch[y == t[z].ch[1]] = x;
    maintain(y);
    maintain(x);
}
void splay(int x)
{
    for (int f = t[x].fa; f = t[x].fa, f; rotate(x))
        if (t[f].fa)
            rotate(get(x) == get(f) ? f : x);
    root = x;
}
void insert(int k)
{
    if (!root)
    {
        t[++tot].val = k;
        t[tot].cnt++;
        root = tot;
        maintain(root);
        return;
    }
    int cur = root, f = 0;
    while (1)
    {
        if (t[cur].val == k)
        {
            t[cur].cnt++;
            maintain(cur);
            maintain(f);
            splay(cur);
            break;
        }
        f = cur;
        cur = t[f].ch[t[f].val < k];
        if (!cur)
        {
            t[++tot].val = k;
            t[tot].cnt++;
            t[tot].fa = f;
            t[f].ch[t[f].val < k] = tot;
            maintain(tot);
            maintain(f);
            splay(tot);
            break;
        }
    }
}
int rnk(int k)
{
    int res = 0, cur = root;
    while (1)
    {
        if (k < t[cur].val)
            cur = t[cur].ch[0];
        else
        {
            res += t[t[cur].ch[0]].size;
            if (k == t[cur].val)
            {
                splay(cur);
                return res + 1;
            }
            res += t[cur].cnt;
            cur = t[cur].ch[1];
        }
    }
}
int kth(int k)
{
    int cur = root;
    while (1)
    {
        if (t[cur].ch[0] && k <= t[t[cur].ch[0]].size)
            cur = t[cur].ch[0];
        else
        {
            k -= t[t[cur].ch[0]].size + t[cur].cnt;
            if (k <= 0)
            {
                splay(cur);
                return t[cur].val;
            }
            cur = t[cur].ch[1];
        }
    }
}
int pre()
{
    int cur = t[root].ch[0];
    if (!cur)
        return cur;
    while (t[cur].ch[1])
        cur = t[cur].ch[1];
    splay(cur);
    return cur;
}
int nxt()
{
    int cur = t[root].ch[1];
    if (!cur)
        return cur;
    while (t[cur].ch[0])
        cur = t[cur].ch[0];
    splay(cur);
    return cur;
}
void del(int k)
{
    rnk(k);
    if (t[root].cnt > 1)
    {
        t[root].cnt--;
        maintain(root);
        return;
    }
    if (!t[root].ch[0] && !t[root].ch[1])
    {
        clear(root);
        root = 0;
        return;
    }
    if (!t[root].ch[0])
    {
        int cur = root;
        root = t[root].ch[1];
        t[root].fa = 0;
        clear(cur);
        return;
    }
    if (!t[root].ch[1])
    {
        int cur = root;
        root = t[root].ch[0];
        t[root].fa = 0;
        clear(cur);
        return;
    }
    int cur = root;
    int x = pre();
    t[t[cur].ch[1]].fa = root;
    t[root].ch[1] = t[cur].ch[1];
    clear(cur);
    maintain(root);
}
int n, op, x;
int main()
{
    scanf("%d", &n);
    while (n--)
    {
        scanf("%d%d", &op, &x);
        if (op == 1)
            insert(x);
        else if (op == 2)
            del(x);
        else if (op == 3)
            printf("%d\n", rnk(x));
        else if (op == 4)
            printf("%d\n", kth(x));
        else if (op == 5)
        {
            insert(x);
            printf("%d\n", t[pre()].val);
            del(x);
        }
        else
        {
            insert(x);
            printf("%d\n", t[nxt()].val);
            del(x);
        }
    }
    return 0;
}

标签:ch,cur,val,int,板子,fa,二叉树,转载,root
From: https://www.cnblogs.com/dreamsincerely/p/16758365.html

相关文章

  • 树结构系列(二):平衡二叉树、AVL树、红黑树
    前面说到二叉树在极端情况下会退化成链表,那如何解决这个问题呢?答案是:树的平衡。我们通过树的平衡,使得左右子树的深度保持在较小范围内,从而保证二叉树的查询效率。这就是平......
  • 树和二叉树
    树的定义:树(Tree)是n(n>=0)个结点的有限集。若n=0,则称空树若n>0,则它满足如下两个条件:(1)有且只有一个特定的称为根(Root)的结点(2)其余结......
  • 二叉树两个节点的最近公共祖先问题
    二叉树两个节点的最近公共祖先问题作者:Grey原文地址:博客园:二叉树两个节点的最近公共祖先问题CSDN:二叉树两个节点的最近公共祖先问题题目描述给定一棵二叉树的头节点......
  • 101.对称二叉树 100.相同的树
    注意compare比较的只是左右节点!!!/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeNoderight;......
  • 226.翻转二叉树,前序遍历解法
    /***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeNoderight;*TreeNode(){}*......
  • 二叉树的最小深度
    二叉树的最小深度一、题目描述给定一个二叉树,找出其最小深度。最小深度是从根节点到最近的叶子节点的最短路径上的节点数量。实例输入:root=[3,9,20,null,null,15,7]......
  • 【转载】PHP:高级分页
    一旦您使用PHP连接到数据库,您就会遇到这样的情况:您希望获得比单个页面上显示的更多的内容。目前普遍存在的解决方案是将您的数据拆分为多个页面,同时显示导航链接以让人......
  • 代码随想录day15 | 102.二叉树的层序遍历 226.反转二叉树 101.对称二叉树
    102.二叉树的层序遍历题目|文章1.迭代思路1.创建一个队列2.确定每一层的节点个数,对每一层进行遍历,将结果输出。实现点击查看代码classSolution{public:ve......
  • 力扣剑指offer——二叉树篇
    ✔✨前言......
  • 高精板子
    搬运的高精板子(忘记出处了)#include<stdio.h>#include<string>#include<string.h>#include<iostream>usingnamespacestd;//compare比较函数:相等返回0,大于返回1,小于......