首页 > 其他分享 >P1377 [TJOI2011] 树的序 (笛卡尔树)

P1377 [TJOI2011] 树的序 (笛卡尔树)

时间:2024-03-18 12:34:36浏览次数:22  
标签:std 二叉 笛卡尔 int 元素 stk TJOI2011 P1377

笛卡尔树模板题

题目给出一个生成序列 要我们构造一个 二叉搜索树。
所以值要满足二叉搜索树的性质。
因为给出的是生成序列,所以序列的下标是满足 最小堆的性质。
那么可以按照满足二叉搜索树的那一维度进行排序也就是值进行排序。
然后进行构建即可。
最后进行先序遍历即可获得答案。

大致的构建方式:
1.先按照值从小到大排序。
2.按照排序顺序一一处理元素。
3.用一个栈来维护笛卡尔树 最右端的一条链
4.每个元素进来后,因为要满足二叉搜索树的性质,所以一定是在这条链上的
5.那么现在就是要确定具体在 最右端的链上的哪个位置进行插入
6.因为此时下标又满足最小堆的性质,所以 栈上维护的链从栈底到栈顶是递增的
7.那么就可以在从栈顶的元素开始找第一个满足小于 当前 元素下标的。
8.找到之后 当前元素就变成 此时栈顶元素的右儿子,原来栈顶的右儿子变成当前元素的左儿子
9.重复 5~8的过程就能完成实现。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int>pir;
const int N = 1e5 + 5;
int ls[N], rs[N], n, stk[N];
pir a[N];
void dfs(int u)
{
    cout << a[u].first << " ";
    if(ls[u])dfs(ls[u]);
    if(rs[u])dfs(rs[u]);
}
void solve()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        cin >> a[i].first;
        a[i].second = i;
    }
    sort(a + 1, a + n + 1);
    int top = 0;
    for(int i = 1; i <= n; i++)
    {
        int k = top;
        while(k > 0 && a[stk[k]].second > a[i].second)k--;
        if(k)rs[stk[k]] = i;
        if(k < top)ls[i] = stk[k + 1];
        stk[++k] = i;
        top = k;
    }
    dfs(stk[1]);
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);

    solve();
}

标签:std,二叉,笛卡尔,int,元素,stk,TJOI2011,P1377
From: https://www.cnblogs.com/pipipipipi43/p/18080099

相关文章

  • 笛卡尔树学习笔记
    笛卡尔树学习笔记定义笛卡尔树是一棵特殊的二叉树,它的每个节点都包含了两个值\((k,w)\)。其中,整棵树关于\(k\)为一棵二叉搜索树,而关于\(w\)为一个小根堆(或大根堆)。到这里可以发现,Treap是一种特殊的笛卡尔树,因为Treap相当于给定了\(k\),而我们人为将其随机了一个\(w\)......
  • 笛卡尔乘积
    SQL中的笛卡尔积SQL中的笛卡尔积是数学集合论中的一个术语。但是,我们也可以在SQL数据库手册中找到这个术语。它意味着什么,我们应该如何使用它?让我们来学习一下。两个集合X和Y的笛卡尔积,表示为X×Y,是所有有序对的集合,其中x在X中,y在Y中。就SQL而言,笛卡尔积是......
  • 编程语言中,差、交、并、自然连接、选择、投影、笛卡尔积分别都是什么运算...
    原文:https://blog.csdn.net/muzihuaner/article/details/119529646交(Intersection):关系R与关系S的交由既属于R又属于S的元组组成,即R与S中相同的元组,组成一个新关系,其结果仍为n目关系。记作:R∩S={t|t∈R∧t∈S}简单来说,运算结果就是两或多个实体集所共有的部分 并(Union):......
  • P2065 [TJOI2011] 卡片 题解
    看大家建图时中间都连了质数点,发一个不用质数点的解法。我们可以先从源点向每一个蓝色卡片对应的点连一条边,再从每一个红色卡片对应的点向汇点连一条边。如果两张卡片可以一起拿走,那就在它们之间连一条边(蓝色连到红色),这些边的最大流量都是\(1\)。建好图以后我们就可以直接用Di......
  • 笛卡尔树学习笔记
    1.定义笛卡尔树是一种特殊的二叉树,同时满足小根堆和二叉搜索树的性质,笛卡尔树的每个节点有两个值(k,w),k满足二叉搜索树性质,w满足小根堆性质。Treap也是一种笛卡尔树2.性质如果k,w是分别两两不同的,那么笛卡尔树也是唯一的对于一颗笛卡尔树,它的中序遍历是原序列a在原序列中......
  • 笛卡尔树
    笛卡尔树定义以一个数列为基础,存储数列中元素,满足两个限制的树。一是数列中元素的下标满足二叉搜索树的性质,二是元素的大小满足堆的性质。建树使用单调栈,在线建树。考虑从左往右在已有的笛卡尔树中添加元素,因为新元素的下标最大,所以只可能取代最右链中的某个元素,并将其收为左......
  • <学习笔记> 笛卡尔树
    笛卡尔树是一种二叉树,每一个节点由键值二元组\((k,w)\)构成,\(k\)满足二叉搜索树的性质,\(w\)满足堆的性质。构建我们可以用一个栈进行构建,假如我们想要求\(k\)满足二叉搜索树的性质,那么我们首先需要按\(k\)从小到大排序,然后一个一个插入;假如我们想要\(w\)满足小根......
  • 数据过多时候,子查询改成left join减少笛卡尔积
    子查询SELECT cn.portal_idASportalId, count(id)ASnumFROM construction_package_wbs_nodecnWHERE cn.delete_flag=0 AND( cn.node_type='单位工程' ORcn.node_type='分部工程' ORcn.node_type='分项工程' ORcn.no......
  • 笛卡尔积
    项目中用到了数据组合问题,使用递归实现笛卡尔积,发现报内存溢出,给出解决办法:1functionDescartes1(list){2letresultList=[];3letsrcLength=list.length;4for(leti=1;i<srcLength;i++){5letpreList=i==1?list[i-1]:r......
  • 笛卡尔树入门
    笛卡尔树的定义笛卡尔树是一种二叉树,每一个结点由一个键值二元组\((k,w)\)构成。要求\(k\)满足二叉搜索树的性质,而\(w\)满足堆的性质。一个有趣的事实是,如果笛卡尔树的\(k,w\)键值确定,且\(k\)互不相同,\(w\)互不相同,那么这个笛卡尔树的结构是唯一的。——OIwiki笛......