LGP1377 [TJTS 2011] 树的序 学习笔记

news/2025/4/19 3:55:35/文章来源:https://www.cnblogs.com/OrinLoong/p/18717873

LGP1377 [TJTS 2011] 树的序 学习笔记

Luogu Link

题意简述

给一个生成序列 \(p\),简单起见 \(p\) 是一个长为 \(n\) 的排列。按照这样的步骤生成一棵二叉搜索树:

  1. 往空树中插入 \(p_i\),则 \(p_i\) 成为当前二叉搜索树的根。
  2. 往非空树 \(u\) 中插入 \(p_i\),若 \(p_i\) 小于 \(u\) 则往左子树走,否则往右子树走。

求出字典序最小的生成序列 \(p'\),使得其可以得到与 \(p\) 相同的序列。

做法简述

思考我们怎么变换 \(p\) 可以生成出一样的BST。
发现在最终生成的树中,父亲一定要早于儿子插入,儿子之间顺序可以互换,左儿子早插入更优。
我们把“早晚关系”转化为时间戳的早晚关系。也就是说满足 \(\text{tim}_u<\text{tim}_{ls_u}<\text{tim}_{rs_u}\)\(p'\) 是最优的。
实际上,\(p'\) 正等价于把 \(p\) 生成的BST前序遍历的结果。

pEKR1nU.png

现在的目标变为建出 \(p\) 生成的树。朴素做最坏是 \(O(N^2)\) 的,怎么加速呢?

实际上,上述时间戳的早晚关系等价于堆的性质。又因为生成树的值又满足BST性质,所以其可以看作一棵以时间戳为值,\(p_i\) 为键的笛卡尔树。所以我们建完树再跑先序遍历就行了!

代码实现

注意不是 dfs(1) 而是 dfs(P[1])

#include <bits/stdc++.h>
using namespace std;
namespace obasic{template <typename _T>void readi(_T &x){_T k=1;x=0;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')k=-1;for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-'0';x*=k;return;}template <typename _T>void writi(_T x){if(x<0)putchar('-'),x=-x;if(x>9)writi(x/10);putchar(x%10+'0');}
};
using namespace obasic;
const int MaxN=1e5+5;
int N,P[MaxN],W[MaxN];
int stk[MaxN],ktp,ls[MaxN],rs[MaxN];
void dfs(int u){printf("%d ",u);if(ls[u])dfs(ls[u]);if(rs[u])dfs(rs[u]);
}
int main(){readi(N);for(int i=1;i<=N;i++)readi(P[i]),W[P[i]]=i;for(int i=1;i<=N;i++){int k=ktp;while(k&&W[stk[k]]>W[i])k--;if(k)rs[stk[k]]=i;if(k<ktp)ls[i]=stk[k+1];stk[++k]=i,ktp=k;}dfs(P[1]);return 0;
}

反思总结

“早晚关系”抽象为时间戳大小关系。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/884612.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vxe-input绑定keyup事件传递的参数

一、VUE3中 Input输入框绑定keyup事件传递的$event 代码一:<script setup>function judgeIsEnterToSerach(event){console.log(event,1111);console.log(event.key,2222);console.log(event.target,230923);console.log(event.target.value,3333);console.log(event.tar…

C#编写ModbusTcp类库

Modbus是一个应用层协议,常用于工业自动化设备之间的通信,主要有两种传输方式:RTU和TCP。用户可能需要支持其中一种或两种,但问题中没有明确说明,所以可能需要先确定这一点。不过,作为类库设计,应该考虑可扩展性,可能先实现TCP,因为相对常见且容易在C#中处理。接下来,…

清华大学推出第二讲 DeepSeek 如何赋能职场应用?从提示语技巧到多场景应用!

前言 清华大学第二讲《DeepSeek如何赋能职场应用》是一份35页的专业文档,详细探讨了DeepSeek在职场中的多场景应用及其赋能作用,从提示语技巧到多场景应用,咱们打工人有福啦!DeepSeek访问地址:https://chat.deepseek.com 清华大学推出的 DeepSeek 从入门到精通(104页)免…

268. 丢失的数字

题目链接 解题思路:利用原有的数组,i位置上的数就是nums[i],但是这里有一个问题,就是如果这个数是n,怎么办?n不能够放到nums[n]上。用一个变量n_index来存n这个数的位置(假设有n这个数),初始化为-1第一种情况:没有n这个数,那么[0, n-1]上都已经放好了,此时n_index为-…

信创

概念 “信创“ (全称“信息技术应用创新”)是国家基于国产芯片和操作系统的PC、服务器、网络设备、存储设备、数据库、中间件等基础设施的技术创新。 信创CPU概览

LGP5854 [LG TPLT] 笛卡尔树 学习笔记

LGP5854 [LG TPLT] 笛卡尔树 学习笔记 Luogu Link 题意简述 给定一个长为 \(n\) 的排列 \(p\),以 \(i\) 为键,\(p_i\) 为值构建 \(p\) 中所有元素的笛卡尔树。 做法解析 定义“右链”为从根开始一直往右儿子走形成的一条链。 因为我们照键从小到大的顺序插入每一个元素,所以…

Linux之proc

proc proc是一个伪文件系统,它提供了内核数据结构的接口。一些/proc文件直接指向了内核的参数。 编辑/proc 文件中的设置与直接编辑内核参数相同。例如vmstat,指令就是读取的/proc/meminfo中的信息。/proc下常见的子文件/proc/cpuinfo:提供 CPU 信息 /proc/meminfo:提供内存…

11.4.3 凸目标的收敛性分析

式\((11.47)\)应该有误,不等号左边还应该有一个项\(-E[||x_T-x^{*}||^2]\),之所以没写估计是因为认为\(x_T\)非常接近\(x^{*}\),所以可以忽略;另外不等号右边的括号打错了,应该是 \[2\underset{t=1}{\overset{T}{\sum}}\eta_tE[R(x_t)]-2S_1R^*-S_2L^2 \],其中\(S_1=\und…