无旋Treap(非指针)实现

#include<bits/stdc++.h>namespace fastIO{template<typename T> inline void input(T& x){T s=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar()) s=(s<<3)+(s<<1)+(ch^'0');x=s*f;}template<typename T> inline void print(T x){if(x<0){putchar('-');x=-x;}if(x>9) print(x/10);putchar(x%10+'0');}template<typename T,typename... Args> inline void input(T& x,Args&... args){input(x);input(args...);}template<typename T> inline void print(T x,char ch){print(x);putchar(ch);}
}
using namespace fastIO;const int N=1e6+5;
struct fhq_treap{//树堆的性质:val(l[u])<val(u)<val(r[u])struct Pair{int l,r;Pair(int l_=0,int r_=0){l=l_;r=r_;}};const int INF=0x3f3f3f3f;int seed=1;int val[N],son[N][2],siz[N],pri[N];//值,第u个节点的左右孩子(0为左,1为右),u为根节点的子树的大小,u的优先级int tot;//节点总数int root=0;//根节点inline int rand1(){return seed*=19260817;}inline void pushup(int u){siz[u]=siz[son[u][0]]+siz[son[u][1]];}Pair split(int u,int k){//根节点为u,按k分裂,返回分裂后两棵子树的根//分裂操作是将一个 Treap 分成 x,y 两个 Treap。其中 x 中每一个结点的值都小于于 k,而 y 中每一个结点的值都大于等于 k。if(!u) return {0,0};//空树if(val[u]<k){//说明其左子树肯定都小于k,在x中,但是在右子树中仍然可能存在值比k小的节点(但肯定比u的值大),所以要继续递归分裂Pair tmp=split(son[u][1],k);son[u][1]=tmp.l;//将右子树中小于k的部分拿出来作为u的右子树,这样整个u都是小于k的,剩下的都是大于等于k的pushup(u);return {u,tmp.r};}else{//同上Pair tmp=split(son[u][0],k);son[u][0]=tmp.r;pushup(u);return {tmp.l,u};}}int merge(int u,int v){//合并u、v两棵子树,返回合并后子树的根//合并是将 x,y 两个 Treap 合并为一个 Treap(因为通常是从同一棵Treap分裂出来的,所以x 中的每一个结点的值都小于等于 y 中每一个结点的值)if(!u || !v) return u+v;//只要有一棵为空,就直接返回另一棵if(pri[u]<pri[v]){//需要满足堆的性质,即根节点的优先级是最小的,所以优先级小的作为合并后的根节点son[u][1]=merge(son[u][1],v); //将右子树和另一棵树合并,作为右子树pushup(u);return u;}else{//反之同理son[v][0]=merge(u,son[v][0]);pushup(v);return v;}}void insert(int k){//插入一个值为 k 的结点//先将申请的一个新的结点作为一棵树 y,并将原来的树分裂成 x,z 两棵树,然后依次合并 x,y,z,就完成了。val[++tot]=k;pri[tot]=rand1();siz[tot]=1;//申请一个节点,作为一棵树,其大小为 1Pair tmp=split(root,k);//以 k 为关键值分裂root=merge(merge(tmp.l,tot),tmp.r);//依次合并,更新根}void erase(int k){//删除值为k的节点//其实很简单,即将整棵树按值分为小于k,等于k与大于k三部分,直接合并小于k与大于k的部分即可Pair x=split(root,k);//分为<和>=两部分Pair y=split(x.r,k+1);//提取=(y.l的根节点)y.l=merge(son[y.l][0],son[y.l][1]);//直接合并左右子树,就能实现删除操作(不用担心会额外删除,多的在右子树里)root=merge(x.l,merge(y.l,y.r));//更新根节点}int queryrank(int k){//根据值查询排名Pair tmp=split(root,k);int res=siz[tmp.l]+1;//小于k的值的数量+1root=merge(tmp.l,tmp.r);//合并回去return res;}int queryval(int k){//根据排名查询值int pos=root;//初始化排名while(pos){if(siz[son[pos][0]]+1==k) return val[pos];//若其左子树大小+1刚好为排名,则说明其就是要找的点(左子树存的是<的,等于的在根节点或右子树,但是不用单独判断右子树,循环会自己跑出来的)if(siz[son[pos][0]]+1<k) pos=son[pos][0];//进入左子树寻找else{//不在左子树也不在根节点,就只能去右子树了pos=son[pos][1];//进入右子树寻找k-=siz[son[pos][0]]+1;//将k减去左子树大小+1(1为根节点大小)(自己模拟一下很容易理解)}}return INF;//以防万一}int getpre(int k){//查找值k的前驱//什么叫“小于 k,且最大的数”?不就是前面的那个数吗,所以直接查找排名比 k 的排名少一的数。return queryval(queryrank(k)-1);}int getnext(int k){//查找k的后驱//值相同的结点可能不止一个,所以不能找后面的那个数了,但是可以将值加一,查询它的排名,并找到对应的值。return queryval(queryrank(k+1));}
};
fhq_treap treap;
int n,m;int main(){input(n,m);for(int i=1;i<=n;++i){int tmp;input(tmp);treap.insert(tmp);}int last=0,ans=0;while(m--){int opt,x;input(opt,x);if(opt==1) treap.insert(x^last);if(opt==2) treap.erase(x^last);if(opt==3){last=treap.queryrank(x^last);ans^=last;}if(opt==4){last=treap.queryval(x^last);ans^=last;}if(opt==5){last=treap.getpre(x^last); ans^=last; }if(opt==6){last=treap.getnext(x^last);ans^=last;}}print(ans,'\n');return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/921089.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入解析:宝塔面板搭建RustDesk教程:告别命令行,一键拥有私有远程桌面

深入解析:宝塔面板搭建RustDesk教程:告别命令行,一键拥有私有远程桌面pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family:…

Windows 安装达梦数据库

1、安装前准备 1.1、最低硬件环境要求CPU 内存 硬盘2 核 2 GB 10 GB 空闲空间1.2、下载达梦数据库安装包官网下载地址:https://eco.dameng.com/download/ 1.3、解压安装包如上图所示,右击安装压缩包,然后点击“全部…

有旋Treap

#include<iostream>using namespace std; /*本代码模拟的是小根堆*/ const int N = 5e5+1, INF = 0x3f3f3f3f; struct node {int l, r, val, pos, siz, cnt; //val:结点的值,pos:随机生成的优先级(尽量避免退…

xxO

1、POJO(Plain Old Java Object) 普通的java对象,没有继承特定类,实现特定接口或特定注解,仅包含字段、getter/setter、构造方法等基础成员。纯粹用于数据存储和传递,可在各层之间通用。POJO更贴近业务本质,代表…

情绪识别论文阅读——Eyemotion - 详解

情绪识别论文阅读——Eyemotion - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mon…

2025年山东设备回收公司TOP交易服务推荐排行榜,济宁,梁山设备回收,二手,饮料,食品,制药,实验室,生产线,化工厂,废旧,大型,专业设备回收公司推荐

工业消防设备在长期使用后,面临更新迭代与淘汰处理的问题,而设备回收环节却存在诸多行业痛点。部分回收企业缺乏专业技术支撑,对缆式线型感温火灾探测器、分布式光纤感温火灾探测器等专用设备的性能判断不准确,导致…

棋盘覆盖难题

棋盘覆盖难题2025-09-28 20:19 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: …

做了个TIFF图片格式转换工具,感觉怎么样?

​在日常办公、图片处理或素材整理场景中,TIFF格式图片因画质高清、支持多层存储的特点被广泛使用,但它也存在文件体积大、兼容性较弱的问题——不少常用软件、社交平台或文档编辑器对TIFF格式支持有限,这时将其转换…

vlookup一定要补足最后的,0)

vlookup一定要补足最后的,0)如题

C#后遗症,掉了个坑,特此记录

String512 str1 = "123123"; 与 String512 str2; str2 = "456"; 有何区别?之前用C#其实是不在意这个问题的,直到今天用CPP写了个String512类,才知道这里面原来还有说法..首先, String512 str1 = …

曾记否 -- Words to be remembered 2025.9.28

曾记否, 在石外楼看旗, 敢面疾风! 节选自 我们的体系, 永不会被表里不一的邪恶势力摧毁一点 -- Words to be remembered 2025.9.28

网站开发需要的技术直接ip访问网站

出品 | 《大咖来了》 一边是企业上云这一毋庸置疑的发展趋势&#xff0c;但另一边&#xff0c;云数据泄露事件的频繁&#xff0c;却让不少企业谈“云”色变。 2020年2月&#xff0c;万豪酒店520万客人信息被泄露&#xff0c;英国信息专员办公室(ICO)对其进行了1840万英镑(约1.…

日常掉坑记录: 关于位操作

char a[8] = { 0x01, 0x02, 0x03, 0x04 };int b = 0;memcpy(&b, a, 4);char c = (b>>8)&0xFF;c是多少?答案: 0x02掉坑原因: 搞反了小端模式下>>符号的操作结果.右移8位, 指的是变量所包含的字节整…

WPF XAML资源文件中的换行、回车、空格及Tab的转义

符号 十六进制 十进制回车 &#x000D; 换行 &#x000A; 空格 &#x0020; Tab &#x0009;

网站怎么做切换中英文免费制作表格的app

无论在我们的工作中还是在我们的生活中&#xff0c;我们都会用到多线程的知识&#xff0c;今天就给大家讲一下如何使用多线程。 序幕 线程的启动 如何使线程暂停 如何使线程停止 线程的优先级 线程安全相关的问题 我们首先要知道进程和线程分别是什么&#xff1f; 进程 - 进…

广州番禺网站公司做那种事情的网站

ChatGPT无限次数:点击直达 ChatGPT 专属指南&#xff1a;利用ChatGPT提升论文写作效率 引言 随着人工智能技术的不断发展&#xff0c;如今许多工具被开发出来&#xff0c;以帮助人们更高效地进行各种工作。其中&#xff0c;ChatGPT作为一个强大的语言生成模型&#xff0c;不仅…

longchain4j 学习系列(2)-调用远程deepseek

接上一篇继续,longchain4j支持open-ai兼容的各种模式,包括deepseek 一、修改pom依赖1 <!-- LongChain4j OpenAI Integration (支持DeepSeek) --> 2 <dependency> 3 <groupId>dev.langchain4j&…

收汇核销简介

收汇核销是我国外汇管理制度中的一项核心环节,目的是确保“货物确实出口、外汇确实收回”,防止虚假出口、骗税、热钱流入等风险。虽然 2012 年起全面电子化,不再盖章,但“核销”逻辑仍在系统后台运行,是出口企业办…

macOS 彻底卸载和重装 Node.js 指南

彻底卸载 Node.js 卸载步骤 # 1. 卸载 npm sudo npm uninstall npm -g# 2. 删除 Node.js 核心文件和配置 sudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /var/db/receipts/org.nodejs.* sudo rm -rf /…

2025最新国内过滤器品牌 TOP10 权威测评推荐厂家与选购指南

随着工业制造、环保水处理、医疗净化等领域的快速发展,过滤器作为关键配套设备,其性能与品质直接影响生产效率、产品质量及环境安全。2025 年国内过滤器市场呈现技术迭代加速、细分场景需求升级的特点,企业对过滤器…