题目描述

志向远大的YY小朋友在学完快速排序之后决定学习平衡树,左思右想再加上SY的教唆,YY决定学习Treap。友爱教教父SY如砍瓜切菜般教会了YY小朋友Treap(一种平衡树,通过对每个节点随机分配一个priority,同时保证这棵平衡树关于priority是一个小根堆以保证效率)。这时候不怎么友爱的510跑了出来,他问了YY小朋友一个极不和谐的问题:怎么求Treap中两个点之间的路径长度。YY秒了之后决定把这个问题交给你来做,但只要求出树中两点的LCA。

输入

第一行两个整数n,m

第二行n个整数表示每个元素的key

第三行n个整数表示每个元素的priority

接下m行,每行一条命令

I A B,插入一个元素,key为A, priority为B

D A,删除一个元素,key为A

Q A B,询问key分别为A和B的LCA的key

输出

对于每个Q输出一个整数。

样例输入

2 1
1 2
4 5
Q 1 2

样例输出

1


题解

权值线段树

一个小结论:不妨设$a\le b$,则Treap中权值为$a$、$b$两点的LCA为权值在$[a,b]$之间,优先级最小的点。

证明:

1.LCA的权值在$[a,b]$之间:考虑从$a$、$b$找到LCA的最后一步:一定是$a$在LCA的非右子树,$b$在LCA的非左子树。否则$a$、$b$在同子树内则LCA可以为更优的该儿子节点。

2.权值在$[a,b]$之间的节点一定都在LCA的子树内:如果不在LCA的子树内,那么节点如果在LCA右侧则一定大于$b$,或在LCA左侧则一定小于$a$。

3.LCA的子树中所有节点的优先级都小于等于LCA:证明显然。

4.LCA一定在LCA的子树内:证明显然。

因此由1、2、3、4得证。

于是只需要对每个数的key维护权值线段树,维护权值在某区间内的数的优先级最小值及其位置。查询时直接区间查询即可。

为了避免一些细节问题(比如两个int加起来爆int之类的),代码中使用了离线离散化。

时间复杂度$O(n\log n)$。

  1. #include <cstdio>
  2. #include <utility>
  3. #include <algorithm>
  4. #define N 100010
  5. #define lson l , mid , x << 1
  6. #define rson mid + 1 , r , x << 1 | 1
  7. #define id(x) lower_bound(v + 1 , v + tot + 1 , x) - v
  8. #define inf 0x7fffffff
  9. using namespace std;
  10. typedef pair<int , int> pr;
  11. int key[N] , pri[N] , opt[N * 3] , qx[N * 3] , qy[N * 3] , v[N << 2] , tot;
  12. pr mn[N << 4];
  13. char str[5];
  14. void build(int l , int r , int x)
  15. {
  16. mn[x] = pr(inf , inf);
  17. if(l == r) return;
  18. int mid = (l + r) >> 1;
  19. build(lson) , build(rson);
  20. }
  21. void insert(int p , int v , int l , int r , int x)
  22. {
  23. if(l == r)
  24. {
  25. mn[x] = pr(v , p);
  26. return;
  27. }
  28. int mid = (l + r) >> 1;
  29. if(p <= mid) insert(p , v , lson);
  30. else insert(p , v , rson);
  31. mn[x] = min(mn[x << 1] , mn[x << 1 | 1]);
  32. }
  33. void erase(int p , int l , int r , int x)
  34. {
  35. if(l == r)
  36. {
  37. mn[x] = pr(inf , inf);
  38. return;
  39. }
  40. int mid = (l + r) >> 1;
  41. if(p <= mid) erase(p , lson);
  42. else erase(p , rson);
  43. mn[x] = min(mn[x << 1] , mn[x << 1 | 1]);
  44. }
  45. pr query(int b , int e , int l , int r , int x)
  46. {
  47. if(b <= l && r <= e) return mn[x];
  48. int mid = (l + r) >> 1;
  49. pr ans(inf , inf);
  50. if(b <= mid) ans = min(ans , query(b , e , lson));
  51. if(e > mid) ans = min(ans , query(b , e , rson));
  52. return ans;
  53. }
  54. int main()
  55. {
  56. int n , m , i;
  57. scanf("%d%d" , &n , &m);
  58. for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &key[i]) , v[++tot] = key[i];
  59. for(i = 1 ; i <= n ; i ++ ) scanf("%d" , &pri[i]);
  60. for(i = 1 ; i <= m ; i ++ )
  61. {
  62. scanf("%s%d" , str , &qx[i]);
  63. if(str[0] == 'I') opt[i] = 1 , scanf("%d" , &qy[i]) , v[++tot] = qx[i];
  64. else if(str[0] == 'D') opt[i] = 2;
  65. else opt[i] = 3 , scanf("%d" , &qy[i]);
  66. }
  67. sort(v + 1 , v + tot + 1);
  68. build(1 , tot , 1);
  69. for(i = 1 ; i <= n ; i ++ ) insert(id(key[i]) , pri[i] , 1 , tot , 1);
  70. for(i = 1 ; i <= m ; i ++ )
  71. {
  72. if(opt[i] == 1) insert(id(qx[i]) , qy[i] , 1 , tot , 1);
  73. else if(opt[i] == 2) erase(id(qx[i]) , 1 , tot , 1);
  74. else if(qx[i] < qy[i]) printf("%d\n" , v[query(id(qx[i]) , id(qy[i]) , 1 , tot , 1).second]);
  75. else printf("%d\n" , v[query(id(qy[i]) , id(qx[i]) , 1 , tot , 1).second]);
  76. }
  77. return 0;
  78. }

【bzoj2770】YY的Treap 权值线段树的更多相关文章

  1. 【bzoj4719】[Noip2016]天天爱跑步 权值线段树合并

    题目描述 给出一棵n个点的树,以及m次操作,每次操作从起点向终点以每秒一条边的速度移动(初始时刻为0),最后对于每个点询问有多少次操作在经过该点的时刻为某值. 输入 第一行有两个整数N和M .其中N代 ...

  2. [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树

    二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...

  3. 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题

    “队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄>     线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...

  4. 动态求区间K大值(权值线段树)

    我们知道我们可以通过主席树来维护静态区间第K大值.我们又知道主席树满足可加性,所以我们可以用树状数组来维护主席树,树状数组的每一个节点都可以开一颗主席树,然后一起做. 我们注意到树状数组的每一棵树都和 ...

  5. 【bzoj3110】[Zjoi2013]K大数查询 权值线段树套区间线段树

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...

  6. 【bzoj3065】带插入区间K小值 替罪羊树套权值线段树

    题目描述 从前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一下,查询区间k小值.他每次向它的随从伏特提出 ...

  7. BZOJ2733/LG3324 「HNOI2014」永无乡 权值线段树合并

    问题描述 BZOJ2733 LG3224 题解 对于每个结点建立一棵权值线段树. 查询操作就去查询第 \(k\) 大,合并操作就合并两颗权值线段树. 并查集维护连通性. 同时 STO hkk,zcr, ...

  8. 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings

    谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...

  9. 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP

    2892: 强袭作战 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 45  Solved: 30[Submit][Status][Discuss] D ...

随机推荐

  1. Sass 语法格式及编译

    一.sass语法格式 这里说的 Sass 语法是 Sass 的最初语法格式,他是通过 tab 键控制缩进的一种语法规则,而且这种缩进要求非常严格.另外其不带有任何的分号和大括号.常常把这种格式称为 S ...

  2. runit git-daemon-run 等错误

    正在处理用于 man-db (2.7.5-1) 的触发器 ... 正在设置 runit (2.1.2-3ubuntu1) ... start: 无法连接到 Upstart: Failed to con ...

  3. JAVA通用BaseServlet的产生和代码实现

    BaseServlet的作用: 我们先写一个工具类:BaseServlet. 我们知道,写一个项目可能会出现N多个Servlet,而且一般一个Servlet只有一个方法(doGet或doPost),如 ...

  4. js函数的默认参数

    function f(flag, start, end, msg){ flag = flag == false ? flag : true; start = start || null; start ...

  5. layer 点击弹出图片

    今天做东西有一个功能:在列表点击图片弹出并放大显示,使用到了layer的页面层,下边是个小demo success:function (e) { var url = e.qrcode_url; //a ...

  6. 学习python第十三天,函数5 装饰器decorator

    定义:装饰器本质是函数,(装饰其他函数)就是为其他函数添加附加功能原则:1.不能修改被装饰的函数的源代码 2.不能修改装饰的函数的调用方式 实现装饰器知识储备1函数即变量2.高阶函数,满足2个条件之一 ...

  7. 基于appium的app自动化测试框架

    基于appium框架的app自动化测试 App自动化测试主要难点在于环境的搭建,appium完全是基于selenium进行的扩展,所以app测试框架也是基于web测试框架开发的 一.设备连接 (即构建 ...

  8. python分布式爬虫--房天下

    第一步安装redis redis在windows系统中的安装与启动: 下载:redis官方是不支持windows操作系统的.但是微软的开源部门将redis移植到了windows上.因此下载地址不是在r ...

  9. [BZOJ3714]Kuglarz(最小生成树)

    Description 魔术师的桌子上有n个杯子排成一行,编号为1,2,-,n,其中某些杯子底下藏有一个小球,如果你准确地猜出是哪些杯子,你就可以获得奖品.花费\(C_{i,j}\)元,魔术师就会告诉 ...

  10. TensorFlow验证码识别

    本节我们来用 TensorFlow 来实现一个深度学习模型,用来实现验证码识别的过程,这里我们识别的验证码是图形验证码,首先我们会用标注好的数据来训练一个模型,然后再用模型来实现这个验证码的识别. 验 ...