首页 > 其他分享 >平衡树模板——splay

平衡树模板——splay

时间:2023-04-14 23:46:34浏览次数:32  
标签:node ch val int tr splay fa 平衡 模板

/*
在splay中
0不能算作是根节点,只能说是一个标记点
如果谁的父亲是0,那么谁就是根节点
*/

#include <bits/stdc++.h>
using namespace std;
const int M=1e5+5;
const int inf=1e9;

#define t tr
#define size siz

int cnt=0,root=0;

struct splay {
    int ch[2],siz,cnt,val,fa;
}tr[M];

int get(int x) {
    return tr[tr[x].fa].ch[1]==x;
}

void up(int x) {
    tr[x].siz=tr[tr[x].ch[0]].siz+tr[tr[x].ch[1]].siz+tr[x].cnt;
}

void rotate(int x) {
    int y=tr[x].fa,z=tr[y].fa;
    int d1=get(x),d2=get(y);
    int son=tr[x].ch[d1^1];
    tr[y].ch[d1]=son;tr[son].fa=y;
    tr[z].ch[d2]=x;tr[x].fa=z;
    tr[x].ch[d1^1]=y;tr[y].fa=x;
    up(y);up(x);
}

void splay(int x,int goal) {
    while(tr[x].fa!=goal) {
        int y=tr[x].fa,z=tr[y].fa;
        int d1=get(x),d2=get(y);
        if(z!=goal) {
            if(d1==d2)rotate(y);
            else rotate(x);
        }
        rotate(x);
    }
    if(goal==0)root=x;
}

int find(int val) {
    int node=root;
    while(tr[node].val!=val&&tr[node].ch[tr[node].val<val])node=tr[node].ch[tr[node].val<val];
    return node;
}


void insert(int val) {
    int node=root,fa=0;
    while(tr[node].val!=val&&node)
        fa=node,node=tr[node].ch[tr[node].val<val];
    if(node)tr[node].cnt++;
    else {
        node=++cnt;
        if(fa)tr[fa].ch[tr[fa].val<val]=node;
        tr[node].siz=tr[node].cnt=1;
        tr[node].fa=fa,tr[node].val=val;
    }
    splay(node,0);
}

int pre(int val,int k) {
    splay(find(val),0);
    int node=root;
    if(k==0&&tr[node].val<val)return node;
    if(k==1&&tr[node].val>val)return node;
    node = tr[node].ch[k];
    while(tr[node].ch[k^1])node=tr[node].ch[k^1];
    return node;
}

void del(int val){
    int last = pre(val,0), next = pre(val,1);
    splay(last , 0); splay(next , last);
    if(t[t[next].ch[0]].cnt > 1){
	    t[t[next].ch[0]].cnt--;
	    splay(t[next].ch[0] , 0);
    }
    else t[next].ch[0] = 0;
}

int kth(int k){
    int node = root;
    if(t[node].size < k) return inf;
    while(1){
	    int son = t[node].ch[0];
	    if(k <= t[son].size) node = son;
	    else if(k > t[son].size+t[node].cnt){
	       k -= t[son].size+t[node].cnt;
	        node = t[node].ch[1];
		}
	    else return t[node].val;
    }
}

int get_rank(int val){
    splay(find(val) , 0);
    return t[t[root].ch[0]].size;
}


int main() {
    insert(-inf);insert(inf);
    int q;cin>>q;
    while(q--) {
        int op,x;
        cin>>op>>x;
        if(op==1)insert(x);
        if(op==2)del(x);
        if(op==3)cout<<get_rank(x)<<endl;
        if(op==4)cout<<kth(x+1)<<endl;
        if(op==5)cout<<tr[pre(x,0)].val<<endl;
        if(op==6)cout<<tr[pre(x,1)].val<<endl;
    }
    return 0;
}

标签:node,ch,val,int,tr,splay,fa,平衡,模板
From: https://www.cnblogs.com/basicecho/p/17320254.html

相关文章

  • 模板元编程与函数式
    参考:【公开课】现代C++进阶:模板元编程与函数式ppt和代码在高性能计算中,一般使用函数式和元编程,而不使用面向对象。简单的介绍:类型自动推导模板参数、模板特化简单的实例:#include<iostream>template<classT>Ttwice(Tt){returnt*2;}std::stringtwice(std::......
  • vue2源码-五、将模板编译解析成AST语法树1
    将模板编译成ast语法树complileToFunction方法vue数据渲染:template模板->ast语法树->render函数,模板编译的最终结果结果就是render函数。在complileToFunction方法中,生成render函数,需要以下两个核心步骤:通过parserHTML方法:将模板(template或html)内容编译成ast语法树通过co......
  • ipconfig /displaydns ipconfig /flushdns
    ipconfig/displaydns显示系统中已经缓存的DNS域名ipconfig/flushdns这是清除DNS缓存用的。当访问一个网站时系统将从DNS缓存中读取该域名所对应的IP地址,当查找不到时就会到系统中查找hosts文件,如果还没有那么才会向DNS服务器请求一个DNS查询,DNS服务器将返回该域名所对应的IP,在......
  • LeetCode 周赛 340,质数 / 前缀和 / 极大化最小值 / 最短路 / 平衡二叉树
    本文已收录到AndroidFamily,技术和职场问题,请关注公众号[彭旭锐]提问。大家好,我是小彭。上周跟大家讲到小彭文章风格的问题,和一些朋友聊过以后,至少在算法题解方面确定了小彭的风格。虽然竞赛算法题的文章受众非常小,但却有很多像我一样的初学者,他们有兴趣参加但容易被题目难......
  • 算法基础模板整理(动态规划篇)
    背包问题01背包问题static const int N = 1010;int dp[N][N], v[N], w[N], n, c;int main(){    cin >> n >> c;    for(int i = 1; i <= n; i ++ ) cin >> v[i] >> w[i];    for(int i = 1; i <= n; i ++ )    ......
  • 算法基础模板整理(基础图论篇)
    拓扑排序bool topo(){    queue<int> q;    for(int u = 1; u <= n; u ++ )        if(!ind[u]) q.push(u);        int cnt = 0;    while(!q.empty()){        int u = q.front();        q.pop(); ......
  • 算法基础模板整理(高阶数据结构篇)
    树状数组动态区间和询问+点修改int lowbit(int x){    return x & -x;}void add(int x, int v){    for(int i = x; i <= n; i += lowbit(i)) tree[i] += v;}int query(int x){    int res = 0;    for(int i = x; i......
  • VMWare Horizon Linux 手动场 cannot open display 错误
    环境:系统:rhel7.9horizonagent版本:2209桌面:Gnome问题描述:防火墙已关闭的情况下,在使用LSF交互式任务时不能打开带界面的程序(xhost+已经事先执行过)。解决问题:vim/usr/lib/vmware/viewagent/bin/StartXServer.sh找到xdmcp_opt="-query127.0.0.1-once"改为xdmcp_opt......
  • 三相不平衡潮流计算matlab 程序采用前推回代法,考虑三相不平衡和互阻抗
    三相不平衡潮流计算matlab程序采用前推回代法,考虑三相不平衡和互阻抗,可通过改变三相负荷和线路参数构建三相不平衡模型,程序运行可靠,有注释ID:7668641878798230......
  • 【D02】Bootstrap免费精选模板推荐,附上Django中使用模板教程
    前端模板-AnchorUIKIT前言今天介绍一款制作精良、开源、免费的Bootstrap模板——AnchorUIKIT该模板使用的是Bootstrapv4版本本文将介绍如何在Django中导入该模板的静态资源包并使用介绍官方文档Anchor-afreeBootstrapUIKit(bootcss.com)预览官方文档......