当前位置: 首页 > news >正文

无旋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.gsyq.cn/news/13631.html

相关文章:

  • 2025年山东设备回收公司TOP交易服务推荐排行榜,济宁,梁山设备回收,二手,饮料,食品,制药,实验室,生产线,化工厂,废旧,大型,专业设备回收公司推荐
  • 棋盘覆盖难题
  • vlookup一定要补足最后的,0)
  • 曾记否 -- Words to be remembered 2025.9.28
  • macOS 彻底卸载和重装 Node.js 指南
  • StatusStrip 状态栏控件的使用
  • unzip-6.0-21.el7.x86_64.rpm怎么安装?CentOS 7手动安装rpm包详细步骤
  • 小迪安全v2023学习笔记(九十讲)—— 小程序篇反编译外在主包分包调整泄露算法逆向未授权
  • 解题报告-序列(alis.*)
  • Cloudbox工具箱!一款拥有100款工具的超级工具箱!Cloudbox工具箱教程(附下载)
  • Lightroom使用教程!一文学会Lightroom使用教程!软件攻略(批量处理)
  • 启发式合并 [PA 2014] Fiolki
  • 完整教程:ISP的前处理和后处理是什么?
  • 《痞子衡嵌入式半月刊》 第 119 期
  • 运动控制卡排名
  • 基于Mysql+SpringBoot+vue框架-在线宠物用品交易网站的设计与实现 - 实践
  • labview打包应用
  • 完整教程:开源的 CSS 动画库
  • 【2025-09-27】连岳摘抄
  • CPU 测试脚本
  • Day23static详解
  • openssh升级
  • 实用指南:月匣 - 百度推出的AI情感陪伴与剧情互动应用
  • 完整教程:整合与超越:论“开源AI智能名片链动2+1模式S2B2C商城小程序”对传统红人直播带货模式的升维
  • 2025 最新隔音板厂家权威推荐排行榜:聚焦实力厂商,阻尼 / 聚酯纤维等全品类适配与标杆案例解析室外/KTV/隔音板安装/沈阳/ 厂房隔音板厂家推荐
  • 2025 年医疗器械注册咨询公司最新权威推荐排行榜:TOP 级服务商全流程能力解析,助力企业高效合规拿证医疗器械注册咨询//二类医疗器械注册咨询/三类医疗器械注册咨询公司推荐
  • 2025 年最新推荐地坪源头厂商权威排行榜:聚焦环氧 / 聚氨酯 / 固化剂等多类型地坪,精选 TOP5 优质企业水性聚氨酯/环氧/密封固化剂地坪施工厂商推荐
  • 算法篇
  • 如何找到当前计算机所有的UnrealEngine安装位置
  • 阿里云函数计算 AgentRun 全新发布,构筑智能体时代的基础设施