我们知道二叉搜索树的中序遍历是一个已经排好序的序列,知道序列我们无法确定树的形态(因为有多种)。

但是,Treap如果告诉我们它的关键字以及权值,那么就可以唯一确定树的形态(Treap的O(logn)的期望时间复杂度就是依靠一个随机堆的深度不会太深)

具体的,已知关键字序列:k1,k2,k3...kn和优先级序列:p1,p2,p3,...pn,

如果我们想要找ki的父亲,只需要找“左边第一个p比它大的和右边第一个p比它大的中,p较小的那个“

至于lca(ki,kj),是对应的pi~pj中的最小值(因为是小根堆)

至于深度,多次找父亲,路径长度就是深度,然后画一下图可以发现轨迹的特点,然后就可以搞了(求两段递增子序列长度)

 /**************************************************************
Problem: 2770
User: idy002
Language: C++
Result: Accepted
Time:6140 ms
Memory:46124 kb
****************************************************************/ #include <cstdio>
#include <vector>
#include <algorithm>
#define oo 0x6FFFFFFF
#define maxn 400010
using namespace std; typedef pair<int,int> dpr; struct Node {
int lf, rg, mid;
dpr st;
bool leaf;
Node *ls, *rs;
} pool[maxn*], *tail=pool, *root;
vector<Node*> stk; int disc[maxn], ntot;
int sv[maxn];
int pr[maxn][]; Node *build( int lf, int rg ) {
Node *nd = ++tail;
nd->lf=lf, nd->rg=rg, nd->mid=(lf+rg)>>;
if( lf==rg ) {
nd->st = dpr( oo, );
nd->leaf = true;
} else {
nd->ls = build( lf, nd->mid );
nd->rs = build( nd->mid+, rg );
nd->st = dpr( oo, );
nd->leaf = false;
}
return nd;
}
dpr qu_min( Node *nd, int lf, int rg ) {
if( lf <= nd->lf && nd->rg <= rg ) return nd->st;
dpr rt = dpr( oo, );
if( lf <= nd->mid )
rt = qu_min( nd->ls, lf, rg );
if( rg > nd->mid )
rt = min( rt, qu_min( nd->rs, lf, rg ) );
return rt;
}
void pushup( Node *nd ) {
nd->st = min( nd->ls->st, nd->rs->st );
}
void modify( Node *nd, int pos, int val ) {
if( nd->leaf ) {
nd->st = dpr( val, pos );
return;
}
if( pos <= nd->mid )
modify( nd->ls, pos, val );
else
modify( nd->rs, pos, val );
pushup( nd );
}
int lca( int u, int v ) {
if( u>v ) swap(u,v);
return qu_min( root, u, v ).second;
} int main() {
int n, m, T;
scanf( "%d%d", &n, &m );
T = n+m;
for( int i=; i<=n; i++ ) {
pr[i][] = ;
scanf( "%d", pr[i]+ );
disc[++ntot] = pr[i][];
}
for( int i=; i<=n; i++ )
scanf( "%d", pr[i]+ );
for( int i=n+; i<=T; i++ ) {
char opt[];
scanf( "%s", opt );
pr[i][] = opt[]=='I' ? :
opt[]=='D' ? : ;
if( pr[i][]== ) {
scanf( "%d%d", pr[i]+, pr[i]+ );
disc[++ntot] = pr[i][];
} else if( pr[i][]== ) {
scanf( "%d", pr[i]+ );
} else {
scanf( "%d%d", pr[i]+, pr[i]+ );
}
}
sort( disc+, disc++ntot );
ntot = unique( disc+, disc++ntot ) - disc - ;
for( int i=; i<=T; i++ ) {
pr[i][] = lower_bound( disc+, disc++ntot, pr[i][] )-disc;
if( pr[i][]== )
pr[i][] = lower_bound( disc+, disc++ntot, pr[i][] )-disc;
}
root = build( , ntot );
for( int i=; i<=T; i++ ) {
if( pr[i][]== ) {
modify( root, pr[i][], pr[i][] );
} else if( pr[i][]== ) {
modify( root, pr[i][], oo );
} else {
int u = pr[i][];
int v = pr[i][];
printf( "%d\n", disc[lca(u,v)] );
}
}
}

bzoj 2770 堆的中序遍历性质的更多相关文章

  1. PAT-2019年冬季考试-甲级 7-4 Cartesian Tree (30分)(最小堆的中序遍历求层序遍历,递归建树bfs层序)

    7-4 Cartesian Tree (30分)   A Cartesian tree is a binary tree constructed from a sequence of distinct ...

  2. [leetcode]_根据二叉树的先序遍历(后序遍历) + 中序遍历 重建二叉树

    题目1:Construct Binary Tree from Preorder and Inorder Traversal 给定一棵二叉树的先序遍历和中序遍历,求重建二叉树. 思路: 1.先序遍历的第 ...

  3. PAT-1167(Cartesian Tree)根据中序遍历序列重建最小堆

    Cartesian Tree PAT-1167 一开始我使用数组进行存储,但是这样可能会导致无法开足够大的数组,因为树如果是链表状的则无法开这么大的数组(虽然结点很少). 正确的解法还是需要建树,使用 ...

  4. 10.26最后的模拟DAY2 改造二叉树[中序遍历+严格递增的最长不下降子序列]

    改造二叉树 [题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随后他 ...

  5. nyoj202_红黑树_中序遍历

    红黑树 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 什么是红黑树呢?顾名思义,跟枣树类似,红黑树是一种叶子是黑色果子是红色的树... 当然,这个是我说的... & ...

  6. 二叉树中序遍历 (C语言实现)

    在计算机科学中,树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构.二叉树是每个节点最多有两个子树的有序树.通常子树被称作“左子树”(left subtre ...

  7. 证明中序遍历O(n)

    算法导论12.1 什么是二叉搜索树 二叉搜索树应满足的性质: 设x是二叉搜索树中的一个结点.如果y是x左子树中的一个结点,那么y.key <= x.key.如果y是右子树中的一个结点,那么y.k ...

  8. C++编程练习(8)----“二叉树的建立以及二叉树的三种遍历方式“(前序遍历、中序遍历、后续遍历)

    树 利用顺序存储和链式存储的特点,可以实现树的存储结构的表示,具体表示法有很多种. 1)双亲表示法:在每个结点中,附设一个指示器指示其双亲结点在数组中的位置. 2)孩子表示法:把每个结点的孩子排列起来 ...

  9. 根据 中序遍历 和 后序遍历构造树(Presentation)(C++)

    好不容易又到周五了,周末终于可以休息休息了.写这一篇随笔只是心血来潮,下午问了一位朋友PAT考的如何,顺便看一下他考的试题,里面有最后一道题,是关于给出中序遍历和后序遍历然后求一个层次遍历.等等,我找 ...

随机推荐

  1. Hash破解神器:Hashcat的简单使用

    Hash破解神器:Hashcat的简单使用 2014-06-10 21:02:42|  分类: 离线密码破解 |  标签:密码字典  rar密码破解  zip密码破解  密码破解  |举报|字号 订阅 ...

  2. 自己看之区间DP

    //菜鸡制作,看的时候可能三目运算符略烦;;; 区间DP入门题:Brackets 地址:http://59.77.139.92/Problem.jsp?pid=1463 分析(对区间DP的代码原理进行 ...

  3. Workqueue机制的实现

    Workqueue机制中定义了两个重要的数据结构,分析如下: cpu_workqueue_struct结构.该结构将CPU和内核线程进行了绑定.在创建workqueue的过程中,Linux根据当前系统 ...

  4. 关于text-decoration无法清除继承的问题

    因为text-decoration的值可以叠加,所以即使设置了none,浏览器也是看成是叠加,而不是清除的意思.

  5. 对 makefile 中 .DEFAULT 的理解

    上例子: all:gao @echo "final".DEFAULT: @echo "In default" 由于 gao 是一个前提条件,但是 makefil ...

  6. webstrom 里面使用github

    1.输入github的账号和密码,点击登录 2.复制github的项目地址,现在clone就行了

  7. UNDO自我理解总结

    [场景] 当在更新数据的时候,发现更新的值写错了,这时就需要将已经更新的地方恢复到原始数据. [基本概念] 在更新的过程中,Oracle会将原始的数据都放入到UNDO里,这样当以上情况发生后,就可以从 ...

  8. leetcode 之Search in Rotated Sorted Array(四)

    描述 Follow up for ”Search in Rotated Sorted Array”: What if duplicates are allowed?    Would this aff ...

  9. csu 1547(01背包)

    1547: Rectangle Time Limit: 1 Sec  Memory Limit: 256 MBSubmit: 996  Solved: 277[Submit][Status][Web ...

  10. 理解 pkg-config 工具(linux编译辅助工具)

    转:http://www.jb51.net/LINUXjishu/86519.html 你在 Unix 或 Linux 下开发过软件吗?写完一个程序,编译运行完全正常,在你本机上工作得好好的,你放到源 ...