zoukankan      html  css  js  c++  java
  • 笛卡尔树

    闲的没事翻新题,突然想起笛卡尔树还没学,于是写了写笛卡尔树的模板题。

    题意

    • 给一个排列p1pn,i号点权值为pi,要求建一棵以编号为关键字的二叉搜索树(中序序列为1n),且以权值为关键字的小根堆。

    • n <= 1e7

    思路分析

    难度在于O(n)建树。但既然编号是连续的,那么我们就每次使劲往右插即可。因此我们要维护一条从根节点一直向右的链

    又因为要维护小根堆性质,每次在链上找到一对相邻点,使得父亲权值大于它,且儿子权值小于它。把儿子设为自己的左儿子,并把自己设为父亲的右儿子即可。

    Code:

    for (register int i = 1; i <= n; ++i) {
    	while (top && val[sta[top]] > val[i])	ls[i] = sta[top--];
    	if (top)	rs[sta[top]] = i;
    	sta[++top] = i;
    }
    

    然而并不知道它有什么用。

    一个不那么显然的性质

    其实还是挺显然的

    笛卡尔树上每个节点的子树中的编号集合一定是一段连续的区间,不过一段连续的区间却不一定是一个连通块。

    实用版建树:

    维护每个点的子树编号区间(这个点一定是区间中的权值的最值点),找出区间中该点左右的最值点,该点向那两个点连边,然后递归子问题。

    例题

    SP3734 PERIODNI - Periodni

    (大概是最经典的笛卡尔树题了)

    给个直方图,问放 (k) 个不在同一行同一列的点的方案数。

    我们发现直方图其实还可以横着划分,划分成一个个方块(见 lhm_大佬的题解),然后会出现树形结构(类似树形依赖关系),用类似树形背包的组合计数DP解决即可。

    题解中的图片

    这个树形结构其实就是笛卡尔树。

    可见,笛卡尔树擅长把序列最值“瓶颈”问题转化为树上的问题。

    P3246 [HNOI2016]序列

    这题似乎是想用笛卡尔树优化rmq的一个log,但似乎那个题解被 hack 了。

    题解在这

    强制在线1e7询问的加强版(在鸽)

    P5044 [IOI2018] meetings 会议

    看不懂题解+看不懂题解代码+不会线段树,可能还要鸽一段时间。

    lsr大佬的题解

    不知道为啥我刚要做,lsr大佬就写好题解了,然后我还看不懂qaq

    2020.8.28 Update:

    写完了。感谢 ywy 学长的讲解!

    笛卡尔树上 DP,用线段树来优化。不过用到笛卡尔树的一个套路:按照最大值把询问区间拆成两半,这样的话每一半都会有一侧是完整的,利用这个性质方便解题。

    jzp 的题解

  • 相关阅读:
    JavaWeb
    JavaWeb
    appium+python实现手机计算器随机计算
    使用uiautomatorviewer工具遇到以下问题-Unexpected error while obtaining UI hierarchy
    appium+python启动手机淘宝
    appium基本环境搭建
    python多个字典“合并”成一个字典
    HTML基础1-图像
    HTML基础1-文本
    RobotFrame简要安装
  • 原文地址:https://www.cnblogs.com/JiaZP/p/13576902.html
Copyright © 2011-2022 走看看