bzoj3196 Tyvj 1730 二逼平衡树

2024-01-10 02:38
文章标签 平衡 tyvj bzoj3196 1730

本文主要是介绍bzoj3196 Tyvj 1730 二逼平衡树,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

传送门

终于把这个大坑填完了。。。
sb树套树
看似最不合理的方案恰恰是正确方案,树套树并不会MLE,它的空间复杂度非常科学,O(nlogn)。(结果因为空间算错数组开小神奇的T掉,浪费了我两天时间)

嘛。貌似除了操作二没什么好说的。转换成判定性问题就好了,二分O(nlog 3 n)解决。其他按照正常线段树和平衡树写就好了。

CODE:

#include<cstdio>
#include<iostream>
using namespace std;
const int N=50005;
struct node
{int size,num,sum;node *ch[2],*fa;inline int getwh(){return fa->ch[0]==this?0:1;}inline void update(){size=ch[0]->size+ch[1]->size+sum;}inline void setch(int wh,node *child);
}pool[2000005],*null,*t[N<<2];
inline void node::setch(int wh,node *child)
{ch[wh]=child;if(child!=null) child->fa=this;update();
}
int a[N];
int n,m,opt,x,y,z,tot;
inline node *getnew(int value)
{node *now=pool+ ++tot;now->ch[0]=now->ch[1]=now->fa=null;now->num=value;now->size=now->sum=1;return now;
}
inline void rotate(node *&now)
{node *fa=now->fa,*grand=fa->fa;int wh=now->getwh();fa->setch(wh,now->ch[wh^1]);now->setch(wh^1,fa);now->fa=grand;if(grand!=null) grand->ch[grand->ch[0]==fa?0:1]=now;
}
inline void splay(node *now,node *tar,node *&root)
{for(;now->fa!=tar;rotate(now))if(now->fa->fa!=tar) now->getwh()==now->fa->getwh()?rotate(now->fa):rotate(now);if(tar==null) root=now;
}
inline void insert(int value,node *&root)
{node *now=root,*last=null;while(now!=null){last=now;if(now->num==value) return now->sum++,now->size++,splay(now,null,root);if(now->num>value) now=now->ch[0];else now=now->ch[1];}if(last==null){root=getnew(value);return;}now=getnew(value);if(last->num>value) last->setch(0,now);else last->setch(1,now);splay(now,null,root);
}
inline node *find(int value,node *&root)
{node *now=root;while(now!=null){if(now->num==value){splay(now,null,root);return now;}if(now->num>value) now=now->ch[0];else now=now->ch[1];}
}
inline void del(int value,node *&root)
{node *now=find(value,root);if(now->sum>1){now->sum--;now->size--;return;}if(now->ch[0]==null&&now->ch[1]==null){root=null;return;}if(now->ch[0]==null){root=now->ch[1];now->ch[1]->fa=null;return;}if(now->ch[1]==null){root=now->ch[0];now->ch[0]->fa=null;return;}node *pre=now->ch[0];while(pre->ch[1]!=null) pre=pre->ch[1];splay(pre,now,root);pre->setch(1,now->ch[1]);pre->fa=null;root=pre;
}
inline int rank(int value,node *&root)
{int ranking=0;node *now=root;while(now!=null){if(now->num==value){ranking+=now->ch[0]->size;splay(now,null,root);return ranking;}if(now->num>value) now=now->ch[0];else ranking+=now->ch[0]->size+now->sum,now=now->ch[1];}return ranking;
}
inline void change(int value,int num,node *&root)
{del(value,root);insert(num,root);
}
inline int pre(int value,node *&root)
{node *now=root;int ans=-2147483647;while(now!=null)if(now->num>=value) now=now->ch[0];else ans=max(ans,now->num),now=now->ch[1];return ans;
}
inline int nxt(int value,node *&root)
{node *now=root;int ans=2147483647;while(now!=null)if(now->num<=value) now=now->ch[1];else ans=min(ans,now->num),now=now->ch[0];return ans;
}
inline void init(int l,int r,node *&root)
{root=null;for(int i=l;i<=r;i++)insert(a[i],root);
}
void build(int l,int r,int now)
{init(l,r,t[now]);if(l==r) return;int mid=(l+r)>>1;build(l,mid,now<<1);build(mid+1,r,now<<1|1);
}
int askrank(int L,int R,int l,int r,int now,int num)
{if(L<=l&&r<=R) return rank(num,t[now]);int mid=(l+r)>>1,ans=0;if(L<=mid) ans=askrank(L,R,l,mid,now<<1,num);if(R>mid) ans+=askrank(L,R,mid+1,r,now<<1|1,num);return ans;
}
inline int askkth(int L,int R,int num)
{int l=0,r=1e8+1,mid;while(l<r){mid=(l+r)>>1;if(askrank(L,R,1,n,1,mid)>=num) r=mid;else l=mid+1;}return l-1;
}
void changenum(int p,int l,int r,int now,int num)
{change(a[p],num,t[now]);if(l==r) return;int mid=(l+r)>>1;if(p<=mid) return changenum(p,l,mid,now<<1,num);changenum(p,mid+1,r,now<<1|1,num);
}
int askpre(int L,int R,int l,int r,int now,int num)
{if(L<=l&&r<=R) return pre(num,t[now]);int mid=(l+r)>>1,ans=-2147483647;if(L<=mid) ans=askpre(L,R,l,mid,now<<1,num);if(R>mid) ans=max(ans,askpre(L,R,mid+1,r,now<<1|1,num));return ans;
}
int asknxt(int L,int R,int l,int r,int now,int num)
{if(L<=l&&r<=R) return nxt(num,t[now]);int mid=(l+r)>>1,ans=2147483647;if(L<=mid) ans=asknxt(L,R,l,mid,now<<1,num);if(R>mid) ans=min(ans,asknxt(L,R,mid+1,r,now<<1|1,num));return ans;
}
int main()
{null=pool;null->ch[0]=null->ch[1]=null->fa=null;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&a[i]);build(1,n,1);while(m--){scanf("%d",&opt);if(opt==1) scanf("%d%d%d",&x,&y,&z),printf("%d\n",askrank(x,y,1,n,1,z)+1);else if(opt==2) scanf("%d%d%d",&x,&y,&z),printf("%d\n",askkth(x,y,z));else if(opt==3) scanf("%d%d",&x,&y),changenum(x,1,n,1,y),a[x]=y;else if(opt==4) scanf("%d%d%d",&x,&y,&z),printf("%d\n",askpre(x,y,1,n,1,z));else scanf("%d%d%d",&x,&y,&z),printf("%d\n",asknxt(x,y,1,n,1,z));}return 0;
}

这篇关于bzoj3196 Tyvj 1730 二逼平衡树的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/589276

相关文章

写给大数据开发:你真的“慢“了吗?揭秘技术与职场的平衡艺术

你是否曾经在深夜里,面对着一个棘手的数据处理问题,感到无比沮丧?或者在一次重要的项目汇报中,突然语塞,无法清晰地表达你的技术方案?作为一名大数据开发者,这些场景可能再熟悉不过。但别担心,因为你并不孤单。让我们一起探讨如何在这个瞬息万变的行业中,既磨练技术利刃,又培养职场软实力。 目录 技术与时间的赛跑1. 长远视角的重要性2. 复利效应在技能学习中的应用 跨界思维:数据结构教我们的职场智

代码随想录 -- 二叉树 -- 平衡二叉树

110. 平衡二叉树 - 力扣(LeetCode) 思路:仍然是递归调用 1. 定义一个递归函数 count 用来计算二叉树的层数 2. isBalanced 函数:如果传入根节点为空返回真;如果根节点 | 左子树的层数 - 右子树的层数 | 大于1,返回假;最后返回根节点左子树、右子树是否是平衡二叉树。 class Solution(object):def count(self,root

构建STM32智能平衡车项目:PID控制算法与蓝牙通信技术

一、项目概述 项目目标和用途 本项目旨在设计和实现一款基于STM32单片机的平衡车。平衡车是一种新型的个人交通工具,广泛应用于短途出行、休闲娱乐等场景。通过本项目,我们希望能够实现一款具备良好稳定性和操控性的平衡车,能够在不同的地形上自如行驶。 解决的问题和带来的价值 平衡车的核心问题在于如何保持其平衡。传统的平衡车往往依赖于复杂的控制算法和高精度的传感器。通过本项目,我们将利用STM32

二叉搜索树、平衡二叉树、B树、B+树、B*树

二叉查找树 二叉查找树,由于不平衡,如果连续插入的数据是有顺序的、会导致如下图B的所示,此时搜索会退化到O(N)   二叉查找树,也称二叉搜索树,或二叉排序树。其定义也比较简单,要么是一颗空树,要么就是具有如下性质的二叉树: (1)若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2) 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3) 任

【C++】【数据结构】一步一步写平衡二叉树[AVL]

转载:有修正,原作者存在一些错误,这里进行了更正。/* 平衡二叉树(Balanced Binary Tree)是二叉查找树的一个进化体第一个引入平衡概念的二叉树。特点:对于每一个结点,它的左右子树的高度之差不能超过1,若插入或删除一个节点之后使得高度之差大于1,就要进行节点之间的旋转,将二叉树重新维持在一个平衡状态。这个方案很好的解决的了二叉查找树退化成链表的问题,把插入,查找,删除的时间复杂度

数据结构(13)——平衡二叉树(红黑树)

欢迎来到博主的专栏——数据结构 博主ID:代码小号 文章目录 红黑树红黑树节点之间的关系红黑树的插入uncle节点为红色uncle节点是黑色或者没有uncle节点 红黑树 平衡二叉树最出名的除了AVL树之外就是红黑树(RBTree),所谓红黑树,即拥有以下特性的平衡二叉树 (1)每个节点要么是红色,要么是黑色 (2)根节点必须是黑色 (3)红色节点的子节点必须是黑色 (

C语言《智能自平衡小车,实现平衡功能的基础上,加入了超声波避障、超声波跟随、蓝牙遥控等功能》+源代码+文档说明

文章目录 源代码下载地址项目介绍项目功能 项目备注源代码下载地址 源代码下载地址 点击这里下载源码 项目介绍 C语言《智能自平衡小车,实现平衡功能的基础上,加入了超声波避障、超声波跟随、蓝牙遥控等功能》+源代码+文档说明 项目功能 为了实现小车功能,小车硬件主要包括: 控制核心板带编码器的直流电机车架12V 1900mah锂电池 项目备注 1、该资源内项目代码都经过

数据结构-高层数据结构:映射/字典(Map)【有序字典:基于二分搜索树、基于平衡二叉树、基于红黑树、基于链表】【无序字典:基于哈希表】

Map.java package map;/*** 映射*/public interface Map<K,V> {/*** 添加元素** @param key* @param value* @return void*/void add(K key,V value);/*** 删除元素** @param key* @return V*/V remove(K key);/*** 查看是

数据结构-高层数据结构:集合(Set)【元素不重复】【基于二分搜索树(有序集合O(logn))、基于平衡二叉树(有序集合O(logn))、基于链表(无序集合O(n))、基于哈希表(无序集合O(n))】

Set.java package set;/*** 集合** @author ronglexie* @version 2018/8/18*/public interface Set<E> {/*** 向集合中添加元素** @param e* @return void* @author ronglexie* @version 2018/8/18*/void add(E e);/*** 删

数据结构-非线性结构-树形结构:有序树 -> 二叉树 -> 平衡二叉树 -> 线段树 (Segment Tree) / 区间树【不是完全二叉树;用于处理区间类数据】【基于静态数组/链表】【竞赛】

平衡二叉树(AVL树):当且仅当任何节点的两棵子树的高度差不大于1的二叉树; 线段树的代码实现 SegmentTree.java /*** 线段树** @author whx* @version 2018/8/25*/public class SegmentTree<E> {/**普通数据*/private E[] data;/**树结构数据*/private E[] tr