每每想要去了解可持久化treap这个好写好调的东东,然后就发现网上只有一个人的——SymenYang的!在此我必须得把他批判一番——写方法不贴代码是什么心态!而且写出来的是有问题的呀!害人不浅!

好吧说正经事,这个版本的treap名叫可持久化treap却没有可持久化,而是借鉴了可持久化treap中的一些写法。貌似可持久化之后反而难写难调。。。在这个版本的treap中加入了堆权值来维护树的形状,然后由三种操作——合并(merge),按size拆分(split_size),按值拆分(split_kth)。先说说merge。merge 这个操作是将两颗子树a,b(b中元素大于等于a中的元素)合并。这是我们这就是一个递归的过程:对于a,b中的当前节点x,y,按照他们的堆权值来确定父亲和儿子的关系,然后再往下递归这个过程,接左儿子还是右儿子看具体的值。然后split中要引入一个nodepair的结构来返回(把一棵拆成两棵得要个结构来返回啊),基本的操作跟在bst上找第k大和前k个的值一致。。具体看代码理解吧。。。 不好画图。。。。

/*
针对的是平衡二叉树那道入门题
*/ #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 200001;
int ans = 0;
struct node{
int key,data,size;
node *son[2];
node(){ key = rand();}
}e[maxn],*root;int ne = 0; struct nodepair{
node* l,*r;
}; nodepair mkpair(node* a,node* b){
nodepair x;
x.l = a, x.r = b;
return x;
} void update(node* x){
if(x){//判断不能少!
x->size = 1;
if(x->son[0]) x->size += x->son[0]->size;
if(x->son[1]) x->size += x->son[1]->size;
}
} node* merge(node* a,node *b){
if(!a) {update(b);return b;}
if(!b) {update(a);return a;}
if(a->key <= b->key){
a->son[1] = merge(a->son[1],b);
update(a); return a;
}
else{
b->son[0] = merge(a,b->son[0]);
update(b); return b;
}
} nodepair split_size(node* a,int k){
if(!a) return mkpair(NULL,NULL);
if(!k) return mkpair(NULL,a);
int ts = a->son[0] ? a->son[0]->size : 0;
nodepair km;
if(ts >= k){
km = split_size(a->son[0],k);
a->son[0] = km.r; update(a);
return mkpair(km.l,a);
}
else{
km = split_size(a->son[1],k - ts - 1);
a->son[1] = km.l; update(a);
return mkpair(a,km.r);
}
} nodepair split_kth(node* a,int k){
if(!a) return mkpair(NULL,NULL);
nodepair km;
if(a->data <= k){
km = split_kth(a->son[1],k);
a->son[1] = km.l; update(a);
return mkpair(a,km.r);
}
else{
km = split_kth(a->son[0],k);
a->son[0] = km.r; update(a);
return mkpair(km.l,a);
}
} node* insert(int v){
node* now = e + ne++;
now->data = v;
nodepair km = split_kth(root,v);
return merge(km.l,merge(now,km.r));
} node* del(int v){
nodepair km1 = split_kth(root,v-1);
nodepair km2 = split_size(km1.r,1);
return merge(km1.l,km2.r);
} void askkth(int k){
node* now = root;
while(true){
int ts = now->son[0] ? now->son[0]->size : 0;
if(ts + 1 == k) break;
else{
if(ts >= k) now = now->son[0];
else k -= ts + 1, now = now->son[1];
}
}
ans = now -> data;
} node* askx(int v){
nodepair km = split_kth(root,v-1);
ans = km.l ? km.l->size+1 : 1;
return merge(km.l,km.r);
} node* pre(int v){
nodepair km1 = split_kth(root,v-1);
nodepair km2 = split_size(km1.l,km1.l->size - 1);
ans = km2.r -> data;
return merge(merge(km2.l,km2.r),km1.r);
} node* sub(int v){
nodepair km1 = split_kth(root,v);
nodepair km2 = split_size(km1.r,1);
ans = km2.l -> data;
return merge(km1.l,merge(km2.l,km2.r));
} int n; void read(){
scanf("%d",&n);
while(n--){
int tmp,op;
scanf("%d%d",&tmp,&op);
if(tmp == 1) root = insert(op);
if(tmp == 2) root = del(op);
if(tmp == 3) root = askx(op);
if(tmp == 4) askkth(op);
if(tmp == 5) root = pre(op);
if(tmp == 6) root = sub(op);
if(tmp == 3 || tmp == 4 || tmp == 5 || tmp == 6) printf("%d\n",ans);
}
} int main(){
read();
return 0;
}

 

好久不见的博客咯!——没有可持久化的可持久化treap的更多相关文章

  1. 好久没有写博客了,发现Live Writer也更新了

    最近由于工作变动,工作内容和心态也有所变化,所以很久没有写博客了,而且我的开源项目深蓝词库转换也很近没有更新了.今天打开LiveWriter发现居然有新版本,于是果断更新.现在新的LiveWriter ...

  2. 利用border和伪类画出三角形 ps:好久没写博客了。。。

    有一个半月没有写博客了,这段时间,小哥我经历了自入行前端最为黑暗的时期,迷茫,空虚,不想写代码,不想做研究了.连打游戏都没有兴趣,如同行尸走肉一般.还好,毕业论文的初稿完成后,整个时间段最恶心最难熬的 ...

  3. c++设计模式总结 好久没写博客了 实在是忙

    具体代码就不贴出来了   通俗易懂的理解方式      原创 c++设计模式: 简单工厂模式 工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品:在工厂中加工产品 ...

  4. python io 模块之 open() 方法(好久没写博客了)

    io.open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True),打开file ...

  5. Kafka 部署指南-好久没有更新博客了

    最近到了一家新公司,很多全新技术栈要理解.每天都在看各类 English Offcial Document,我的宗旨是我既然看懂了,就写下来分享,这是第一篇. 基本需求: 1.已有 zookeeper ...

  6. Python爬取CSDN博客文章

    0 url :http://blog.csdn.net/youyou1543724847/article/details/52818339Redis一点基础的东西目录 1.基础底层数据结构 2.win ...

  7. 如何使用 Hexo 搭建个人博客

    原文链接 什么是 Hexo ? Hexo 是一个简单快速的静态博客框架,可以通过编辑 Markdown 文档生成好看的静态博客. 搭建 Hexo 要求 安装 Hexo 十分简单,只需要 Node.js ...

  8. 基于.NetCore开发博客项目 StarBlog - (17) 自动下载文章里的外部图片

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  9. 全栈一路坑之使用django创建博客

    最近在看一篇全栈增长工程师实战,然后学习里面的项目,结果发现作者用的技术太过老旧,好多东西都已经被抛弃了,所以结合着官方文档和自己的一些理解将错误的信息替换一下,边写边学习 准备工作和工具 作者说需要 ...

随机推荐

  1. 【JS学习】慕课网8-17编程练习 网页的返回与跳转

    编程练习 制作一个跳转提示页面: 要求: 1. 如果打开该页面后,如果不做任何操作则5秒后自动跳转到一个新的地址,如慕课网主页. 2. 如果点击“返回”按钮则返回前一个页面. 代码如下: 需要注意的是 ...

  2. 转帖 maven(一) maven到底是个啥玩意~

    转载自:https://www.cnblogs.com/whgk/p/7112560.html 我记得在搞懂maven之前看了几次重复的maven的教学视频.不知道是自己悟性太低还是怎么滴,就是搞不清 ...

  3. spark window本地运行wordcount错误

    在运行本地运行spark或者hadoop代码时可能会遇到一下三种问题   1.Exception in thread "main" java.lang.UnsatisfiedLin ...

  4. vue 项目 跳转 页面 不刷新 问题

    vue项目中需要导出下载客户数据,因为数据太多,响应太慢.后台直接上传给七牛  然后返回一个下载链接  前端通过跳转链接 来下载 riskManagementApi.friendExprotAll(t ...

  5. 【LeetCode 4】寻找两个有序数组的中位数

    题目链接 [题解] 假设在两个有序的序列中找第k小的数字. 那么我们先定位第一个序列中的第k/2个数字(不足则取最边上的那个数字)记下标为i1 然后定位第二个序列中的第k/2个数字(同样不足则取最边上 ...

  6. 生产环境用到的几个有用的Linux命令

    有时候,几个有用的Linux命令可以很大的提高你的工作效率. 1.free -m 这个命令我暂时就只会这么使用,它可以查看服务器的内存资源 2.top 这个命令同样可以查看服务器的资源,当然我还是用它 ...

  7. (转)Linux环境进程间通信----系统 V 消息队列列

    转:http://www.ibm.com/developerworks/cn/linux/l-ipc/part3/ 消息队列(也叫做报文队列)能够克服早期unix通信机制的一些缺点.作为早期unix通 ...

  8. jquery中的ajax方法参数的用法和他的含义

    jquery中的ajax方法参数的用法和他的含义: 1.url:  要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type:  要求为String类型的参数,请求方式(pos ...

  9. 解决 html5 input type='number' 类型可以输入e

    当给 input 设置类型为 number 时,比如,我想限制,只能输入 0-9 的正整数,正则表达式如下: /^[-]?$/ // 匹配 0-9 的整数且只匹配 0 次或 1 次 用正则测试,小数点 ...

  10. linux网卡驱动更新方法

    kernel: eth0: igb_reset_task: Reset adapter解决方法 1. LVS集群web项目,运行大概一个月左右出现访问慢的情况,查询mysql服务器时/var/log/ ...