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

【笛卡尔树】

笛卡尔树

  • 笛卡尔树
      • 定义
      • 构建
      • 性质
    • 习题
      • P6453 [COCI 2008/2009 #4] PERIODNI
      • CF1913D Array Collapse
      • P4755 Beautiful Pair
      • [ARC186B] Typical Permutation Descriptor

笛卡尔树

定义

笛卡尔树是一种二叉树,每一个节点由一个键值二元组 ( k , w ) (k,w) (k,w) 构成。要求 k k k 满足二叉搜索树的性质,而 w w w 满足堆的性质。如果笛卡尔树的 k , w k,w k,w 键值确定,且 k k k 互不相同, w w w 也互不相同,那么这棵笛卡尔树的结构是唯一的。

通俗的讲,笛卡尔树是一个二叉树,中序遍历是原序列,同时满足堆性质。

构建

以小根堆笛卡尔树为例。

法1
在这里插入图片描述
观察上图笛卡尔树,我们发现,一个节点的父亲就是 左边第一个比它小的右边第一个比它小的 的较大的那个。

写个单调栈来回跑两遍即可。

法2
我们考虑将元素按下标顺序依次插入到当前的笛卡尔树中。那么每次我们插入的元素必然在这棵树的右链(右链:即从根节点一直往右子树走,经过的节点形成的链)的末端。于是我们执行这样一个过程,从下往上比较右链节点与当前节点 u u u w w w,如果找到了一个右链上的节点 x x x 满足 w x < w u w_x<w_u wx<wu,就把 u u u 接到 x x x 的右儿子上,而 x x x 原本的右子树就变成 u u u 的左子树。

下图红框部分就是我们始终维护的右链:

在这里插入图片描述
模板P5854

	cin>>n;for(int i=1;i<=n;i++){cin>>a[i];while(Sid&&a[S[Sid]]>a[i])Sid--;l[i]=S[Sid+1];if(Sid)r[S[Sid]]=i;S[++Sid]=i;S[Sid+1]=0;}

性质

  • 区间 [ l , r ] [l,r] [l,r] 的极值所在为 l , r l,r l,r 在笛卡尔树上的 LCA。
  • 每个数左右两边第一个比它大/小的数分别是它在笛
    卡尔树上的父亲和“拐点祖先”。
  • 随机笛卡尔树的树高是 O ( log ⁡ n ) O(\log n) O(logn) 的。

习题

P6453 [COCI 2008/2009 #4] PERIODNI

在这里插入图片描述

1 ≤ n , k ≤ 500 1\le n,k\le 500 1n,k500,层高不会超过 1 0 6 10^6 106

考虑在第 i i i 列和第 j j j 列 的第 h h h 层都放了一个数,那么要求中间断开,即 min ⁡ k = i j a i < h \min_{k=i}^j a_i <h mink=ijai<h,其中 a i a_i ai 为第 i i i 列层数。

考虑建出小根堆笛卡尔树。

在这里插入图片描述

分成了若干矩形,树形DP即可。

CF1913D Array Collapse

link

在这里插入图片描述
1 ≤ n ≤ 3 × 1 0 5 , 1 ≤ p i ≤ 1 0 9 1\le n\le 3\times 10^5,1\le p_i \le 10^9 1n3×105,1pi109

  • 考虑建立一棵小根堆笛卡尔树。
  • 每个子树的根节点对应一段区间 [ l , r ] [l,r] [l,r] 的最小值的位置 x x x
  • 左子树表示 [ l , x − 1 ] [l,x-1] [l,x1],右子树表示 [ x + 1 , r ] [x+1,r] [x+1,r]
  • f u f_u fu 表示以 u u u 为根(即区间 [ l , r ] [l,r] [l,r] )的方案数,也记为 f [ l , r ] f[l,r] f[l,r]
  • 如果不删除 u u u,方案为 f [ l , x − 1 ] × f [ x + 1 , r ] f[l,x-1] \times f[x+1,r] f[l,x1]×f[x+1,r]
  • 考虑删除 u u u,因为是在笛卡尔树上 dp。
  • 所以如果 l > 1 l>1 l>1,那么 u u u 可以被左边删掉,方案数为 f [ x + 1 , r ] f[x+1,r] f[x+1,r]
  • 同理 r < n r<n r<n,方案数为 f [ l , x − 1 ] f[l,x-1] f[l,x1]
  • 如果都能被两边删除,算重的方案为 1 1 1(全部删掉)。

P4755 Beautiful Pair

link
在这里插入图片描述
1 ≤ n ≤ 1 0 5 , 1 ≤ a i ≤ 1 0 9 1\le n \le 10^5,1\le a_i\le 10^9 1n105,1ai109

  • 考虑建立一棵大根堆笛卡尔树。
  • 同上一题,每个子树的根节点对应一段区间 [ l , r ] [l,r] [l,r] 的最大值的位置 x x x
  • 类似分治,考虑计算跨过 x x x 的方案数。
  • 枚举短的一边(不妨假设是左边),设 i ∈ [ l , x ] i\in[l,x] i[l,x],那么需要查询 [ x , r ] [x,r] [x,r] ≤ a x a i \large \le \frac{a_x}{a_i} aiax的数的个数。
  • 容易证明枚举次数不超过 n log ⁡ n n\log n nlogn次。
  • 直接主席树维护即可。

[ARC186B] Typical Permutation Descriptor

link

在这里插入图片描述

1 ≤ N ≤ 3 × 1 0 5 , 0 ≤ A i < i 1\le N \le 3\times 10^5,0\le A_i< i 1N3×105,0Ai<i

不难发现 P A i P_{A_i} PAi 即是 i i i 左边第一个比 A i A_i Ai 小的数,根据这一点建立笛卡尔树,则原问题变为在笛卡尔树上填数的方案数,简单DP即可。

http://www.lryc.cn/news/536010.html

相关文章:

  • Java堆外内存的高效利用与性能优化
  • 【Unity3D优化】使用ASTC压缩格式优化内存
  • iptables网络安全服务详细使用
  • MiC建筑引领未来:中建海龙的探索与实践
  • 清华精品资料:DeepSeek从入门到精通、DeepSeek赋能职场
  • Nginx进阶篇 - nginx多进程架构详解
  • SpringBoot初始化8个常用方法
  • boolen盲注和时间盲注
  • CTF-web:java-h2 堆叠注入rec -- N1ctf Junior EasyDB
  • TUSB422 MCU 软件用户指南
  • BUU37 [DASCTF X GFCTF 2024|四月开启第一局]web1234100
  • 常见的排序算法:插入排序、选择排序、冒泡排序、快速排序
  • vue学习9
  • TDengine 性能测试工具 taosBenchmark
  • 【xdoj离散数学上机】T283
  • Javaweb中,使用Servlet编写简单的接口
  • GESP5级语法知识(十):初级数论(三)
  • “PEP 8: W292 no newline at end of file“报错 IntelliJ IDEA自动添加空行问题
  • ComfyUI工作流 FluxRedux基础换装
  • 【机器学习】常见采样方法详解
  • 使用瑞芯微RK3588的NPU进行模型转换和推理
  • Flutter项目试水
  • 【算法学习】DFS与BFS
  • 100.16 AI量化面试题:监督学习技术在量化金融中的应用方案
  • 基于deepseek api和openweather 天气API实现Function Calling技术讲解
  • 线性数据结构解密:数组的定义、操作与实际应用
  • CentOS搭建PPPOE服务器
  • 【报错】解决 RuntimeError: CUDA error: CUBLAS_STATUS_INVALID_VALUE 报错问题
  • 【C语言】C语言 文具店商品库存管理系统(源码+数据文件)【独一无二】
  • LangChain系列: 使用工具和工具包构建代理实战教程