当前位置: 首页 > 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.jsqmd.com/news/5656/

相关文章:

  • 深入解析:宝塔面板搭建RustDesk教程:告别命令行,一键拥有私有远程桌面
  • Windows 安装达梦数据库
  • 有旋Treap
  • xxO
  • 情绪识别论文阅读——Eyemotion - 详解
  • 2025年山东设备回收公司TOP交易服务推荐排行榜,济宁,梁山设备回收,二手,饮料,食品,制药,实验室,生产线,化工厂,废旧,大型,专业设备回收公司推荐
  • 棋盘覆盖难题
  • 做了个TIFF图片格式转换工具,感觉怎么样?
  • vlookup一定要补足最后的,0)
  • C#后遗症,掉了个坑,特此记录
  • 曾记否 -- Words to be remembered 2025.9.28
  • 日常掉坑记录: 关于位操作
  • WPF XAML资源文件中的换行、回车、空格及Tab的转义
  • longchain4j 学习系列(2)-调用远程deepseek
  • 收汇核销简介
  • macOS 彻底卸载和重装 Node.js 指南
  • 2025最新国内过滤器品牌 TOP10 权威测评推荐厂家与选购指南
  • Python 将 HTML 转换为纯文本 TXT (HTML 文本提取) - 实践
  • 软件工程第一次作业——物品复活系统
  • 完整教程:【C++】string类的常见接口的使用
  • 【Android之路】界面和状态交互 - 详解
  • StatusStrip 状态栏控件的使用
  • unzip-6.0-21.el7.x86_64.rpm怎么安装?CentOS 7手动安装rpm包详细步骤
  • 2025过滤器厂家最新推荐TOP5排行榜:覆盖环保过滤器、精密过滤器、高效过滤器,帮企业找到适配优质厂商
  • 实用指南:零基础学AI大模型之LangChain
  • ubi文件系统的 制作 + 挂载
  • 一款开源免费、组件丰富的 WPF UI 控件库,提供了 100 多款常用控件!
  • 元推理用无限嵌套,取代目前弱ai的暴力无限试错
  • 小迪安全v2023学习笔记(九十讲)—— 小程序篇反编译外在主包分包调整泄露算法逆向未授权
  • 解题报告-序列(alis.*)