洛谷 P1377 [TJOI2011]树的序 (单调队列优化建BST


链接

题意分析

本题思路很简单,根据题意,我们利用所给的Bst生成序将Bst建立起来,然后输出该BST的先序遍历即可;

但,如果我们不加优化,建BST的时间复杂度在最劣情况下将达到O(n^2),显然,在1e5的数据下是过不去的,所以我们考虑利用利用单调队列优化来建BST;

算法思路

BST建树本质上便是按照权值将新加入节点插入到对应的位置,该过程受插入顺序

影响

我们考虑可以将读入的生成序列的下标变成权值,本身权值变为下标

for(int i=1;i<=n;i++){
x=read();
a[x]=i;
}

因为权值为1-n的序列,我们将该数组从1-n遍历,本质便是按权值从小到大遍历(如

果权值不是1-n的序列,将其离散化即可)

我们按该方式维护一个单调队列,当一个新数进队列后不在向前更新时,我们便将

该节点插到单调队列中它左侧节点的右子树中,原因很简单,该节点左侧的节点先

入队列,说明左侧权值一定比该节点小,故将该点插入到左侧节点的右子树上,假设

该节点进队列过程中压掉了节点,则将该节点插入到被它压掉的最后一个节点的左

子树上,我们用此方法便可以在O(n)的时间复杂度下建成一颗bst了,建树代码如下

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

为什这样建树可以建出正确的bst呢?

我们举个例子

比如3 2 4 1这个序列

排序后变为了1(4) 2(2) 3(1) 4(3)

括号内为权值,括号外为下标

第一步,插入1(4)

第二步,插入2(2)因为在单调队列中我们将其压掉了所以,将1(4)a插入到2(2)的左子树中

第三步

同理

第四步,目前单调队列中只有3(1)新点4(3)进入后无法压掉3(1)便放在3(1)的左子树中

建树完毕,我们按权值加入,每进入一个点便插入到目前的合适位置,当更优的点

出现时,倘若恰好将此点压掉,我们便将上一个点与该点的连接关系断开,将新节

点插入到这两个节点之间,如下图

红色为新加入节点

为什么后续加入的节点不会插到以经压入的节点下呢?得益于我们加入节点是按权值从小到大加入的

比如说上图,既然红色节点已经入队列了,能红色节点的子树中插入的节点一定小于红色节点的权值,但已经没有了

这就是整个算法的思路

完整代码如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=1e6+10;
inline int read(){
int ret=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-'){
f=-f;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
ret=ret*10+(ch^'0');
ch=getchar();
}
return ret*f;
}
int q[maxn];
int l[maxn];
int r[maxn];
int a[maxn];
int n;
void dfs(int ro){
if(!ro){
return ;
}
cout<<ro<<" ";
dfs(l[ro]);
dfs(r[ro]);
return ;
}
int main(){
n=read();
int x;
for(int i=1;i<=n;i++){
x=read();
a[x]=i;
}
int tot=0;
int pos=0;
for(int i=1;i<=n;i++){
tot=pos;
while(pos&&a[q[pos]]>a[i]){
pos--;
}
if(pos){
r[q[pos]]=i;
}
if(pos<tot){
l[i]=q[pos+1];
}
q[tot=++pos]=i;
}
dfs(q[1]);
return 0;
}

完结撒花!

单调队列优化O(N)建BST P1377 [TJOI2011]树的序的更多相关文章

  1. 洛谷 P1377 [TJOI2011]树的序 解题报告

    P1377 [TJOI2011]树的序 题目描述 众所周知,二叉查找树的形态和键值的插入顺序密切相关.准确的讲:1.空树中加入一个键值\(k\),则变为只有一个结点的二叉查找树,此结点的键值即为\(k ...

  2. Luogu P1377 [TJOI2011]树的序:离线nlogn建二叉搜索树

    题目链接:https://www.luogu.org/problemnew/show/P1377 题意: 有一棵n个节点的二叉搜索树. 给出它的插入序列,是一个1到n的排列. 问你使得树的形态相同的字 ...

  3. [洛谷 P1377] TJOI2011 树的序

    问题描述 众所周知,二叉查找树的形态和键值的插入顺序密切相关.准确的讲:1.空树中加入一个键值k,则变为只有一个结点的二叉查找树,此结点的键值即为k:2.在非空树中插入一个键值k,若k小于其根的键值, ...

  4. BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP

    BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...

  5. BZOJ 2806: [Ctsc2012]Cheat [广义后缀自动机 单调队列优化DP 二分]

    2806: [Ctsc2012]Cheat 题意: 多个主串和多个询问串,每次询问将询问串分成多个连续子串,如果一个子串长度>=L且在主串中出现过就是熟悉的 如果熟悉的字符串长度>=询问串 ...

  6. 2018.09.06 烽火传递(单调队列优化dp)

    描述 烽火台是重要的军事防御设施,一般建在交通要道或险要处.一旦有军情发生,则白天用浓烟,晚上有火光传递军情. 在某两个城市之间有 n 座烽火台,每个烽火台发出信号都有一定的代价.为了使情报准确传递, ...

  7. Mice and Holes 单调队列优化dp

    Mice and Holes 单调队列优化dp n个老鼠,m个洞,告诉你他们的一维坐标和m个洞的容量限制,问最小总距离.1 ≤ n, m ≤ 5000. ​ 首先列出朴素的dp方程:\(f[i][j] ...

  8. BZOJ 2806 [Ctsc2012]Cheat ——后缀自动机 单调队列优化DP

    先建出广义后缀自动机. 然后跑出文章中每一个位置的最大匹配距离. 然后定义$f[i]$表示匹配到以$i$结尾的串时,最长的匹配距离. 显然可以二分$L$的取值. 然后容易得到$DP$方程 $f[i]= ...

  9. 【BZOJ2806】【CTSC2012】Cheat - 广义后缀自动机+单调队列优化DP

    题意: Description Input 第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库的行数 接下来M行的01串,表示标准作文库 接下来N行的01串,表示N篇作文 Output N行 ...

随机推荐

  1. .sync 修饰符

    vue 修饰符sync的功能是:当一个子组件改变了一个 prop 的值时,这个变化也会同步到父组件中所绑定 //写一个(子)组件Child.vue <template> <div c ...

  2. 简单实现C++Stack模板

    栈的特点是先进后出以及只能在栈顶进行插入和删除操作 本次实现的栈的基本操作: 1)弹栈 2)压栈 3)求栈大小 4)求栈容量 5)判断栈空 6)获取栈顶元素 1.用数组的方式实现栈基本操作 /** * ...

  3. 为何要做seo关键词排名

    http://www.wocaoseo.com/thread-229-1-1.html 武汉seo百度指数在150左右,做seo的同仁们都知道这样的一件事情. 真正搜索武汉seo关键词能作为潜在客户的 ...

  4. 基于Log4Net记录日志到SQLServer(自定义字段)

    本文记录通过log4net将日志信息记录到SQLServer数据库中. 1.新建控制台应用程序 Log4NetDemo: 2.通过NuGet安装Log4Net (项目版本2.0.8): 3.项目根目录 ...

  5. unity 模板测试 详解

    https://blog.csdn.net/u011047171/article/details/46928463#t4

  6. 读Twinsen的深入探索透视投影变换

    2017.10.16更新,分割线下面是以前的文字,有表达的意思,却言不达意,实属羞耻,看官只需看前面文字即可. Twinsen大神的<深入探索透视投影变换>有几个点说得不够清晰,我这里提一 ...

  7. Anchors Piovt详解

    这个两个东西是RectTransform里面的两个属性,也是UGUI做UI自适应的重要工具,之前做的的时候,都只是调出效果即可,并没有深究其中的原理,现在决定来补上这个漏洞. 首选我们来看看Ancho ...

  8. 《神经网络的梯度推导与代码验证》之vanilla RNN的前向传播和反向梯度推导

    在本篇章,我们将专门针对vanilla RNN,也就是所谓的原始RNN这种网络结构进行前向传播介绍和反向梯度推导.更多相关内容请见<神经网络的梯度推导与代码验证>系列介绍. 注意: 本系列 ...

  9. Leetcode 1577 数的平方等于两数乘积的方法数

    Leetcode 1577 数的平方等于两数乘积的方法数 题目 给你两个整数数组 nums1 和 nums2 ,请你返回根据以下规则形成的三元组的数目(类型 1 和类型 2 ): 类型 1:三元组 ( ...

  10. 2020年1月31日 安装Python的requests包记录

    C:\Users\ufo>pip install requests Collecting requests WARNING: Retrying (Retry(total=, connect=No ...