知识点

一 . 笛卡尔树 Cartesian Tree

笛卡尔树中的节点及元素满足以下两个性质:

① 树中的元素满足二叉搜索树性质,要求按照中序遍历得到的序列为原数组序列

② 树中节点满足性质,根节点的值要大于其左右子节点的值

二 . 四毛子算法 Method of Four Russians

(待填坑)


模板题

洛谷 P5854 【模板】笛卡尔树

题目描述

给定一个  的排列 p,构建其笛卡尔树。

即构建一棵二叉树,满足:

  1. 每个节点的编号满足二叉搜索树的性质。
  2. 节点 i 的权值为 ,每个节点的权值满足小根堆的性质。

输入格式

第一行一个整数 n。

第二行一个排列 ​。

输出格式

设  分别表示节点 i 的左右儿子的编号(若不存在则为 0)。

一行两个整数,分别表示  和 

输入输出样例

输入 #1

5
4 1 3 2 5

输出 #1

19 21

说明/提示

【样例解释】

i
1 0 0
2 1 4
3 0 0
4 3 5
5 0 0

【数据范围】

对于 30% 的数据,

对于 60% 的数据,

对于 80% 的数据,

对于 90% 的数据,

对于 100% 的数据,

(待填坑)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define ll long long
#define re register
using namespace std;
int n,top=0,k=0;
ll int L,R;
const int maxn=1e7+5,INF=0x3f3f3f3f;
int a[maxn],left_tree[maxn],right_tree[maxn],s[maxn];inline int read()
{int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}return x*f;
}inline void make_tree(int l,int r) //使用单调栈维护建树
{for(re int i=l;i<=r;++i){k=top;while(k&&a[s[k]]>a[i]) k--;if(k) right_tree[s[k]] =i;if(k<top) left_tree[i]=s[k+1];s[++k]=i;top=k;}
}int main()
{n=read();for(re int i=1;i<=n;++i){a[i]=read();}make_tree(1,n);for(re int i=1;i<=n;++i){L^=1ll*i*(left_tree[i]+1); //要转换成long long形式R^=1ll*i*(right_tree[i]+1);}printf("%lld %lld",L,R);return 0;
}

相关练习

1 . 洛谷 P3793 由乃救爷爷

思路:题目很长,但有用的信息缩减得:有个数,个询问,每次询问问区间[l,r]中的最大值。可以用笛卡尔树求RMQ最值。

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
/****随机数生成器,题目已给出****/
namespace GenHelper
{unsigned z1,z2,z3,z4,b;unsigned rand_(){b=((z1<<6)^z1)>>13;z1=((z1&4294967294U)<<18)^b;b=((z2<<2)^z2)>>27;z2=((z2&4294967288U)<<2)^b;b=((z3<<13)^z3)>>21;z3=((z3&4294967280U)<<7)^b;b=((z4<<3)^z4)>>12;z4=((z4&4294967168U)<<13)^b;return (z1^z2^z3^z4);}
}
void srand(unsigned x)
{using namespace GenHelper;
z1=x; z2=(~x)^0x233333333U; z3=x^0x1234598766U; z4=(~x)+51;}
int read()
{using namespace GenHelper;int a=rand_()&32767;int b=rand_()&32767;return a*32768+b;
}/***构造笛卡尔树及查询函数***/
int n,m,s;
const int maxn=20000005;
int a[maxn],ltree[maxn],rtree[maxn],st[105];int query(int l,int r) //找到当前区间的最大值
{int rt=st[1];for(;;){if(l<=rt && rt<=r) return a[rt];if(rt<r) rt=rtree[rt];else rt=ltree[rt];}
}void make_tree() //笛卡尔树有两种写法
{int top=0;for(int i=1;i<=n;++i){int k=0;while(top&&a[st[top]]<=a[i]) k=st[top--];ltree[i]=k;if(top) rtree[st[top]]=i;st[++top]=i;}}int main()
{cin>>n>>m>>s;srand(s);for(int i=1;i<=n;++i){a[i]=read();}    make_tree();unsigned long long ans=0;int l,r;for(int i=1;i<=m;++i){l=read()%n+1; r=read()%n+1;if(l>r) swap(l,r);ans+=query(l,r);}cout<<ans;return 0;
}

2 .  洛谷 P1377 [TJOI2011] 树的序

思路:由题得:给一个生成序列,建出一棵笛卡尔树,求字典序最小的可以得到相同笛卡尔树的生成序列,最后进行笛卡尔树的先序遍历。

进行先序遍历的原因:根据二叉搜索树的性质,其先序的字典序最小,先要确认根节点的位置,再确认左子树,最后确认右子树

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,k=0,top=0;
const int maxn=1e7+5;
int a[maxn],st[maxn],ltree[maxn],rtree[maxn];
inline int read()
{int x=0,f=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}return x*f;
}inline void dfs(int x)
{if(x!=0) {printf("%d ",x); //输出根节点后进行左右子树的查找dfs(ltree[x]);dfs(rtree[x]);}
}int main()
{n=read();for(int i=1;i<=n;++i){int x=read();a[x]=i; //转换成输入的值的序号进行建树}for(int i=1;i<=n;++i){k=top;while(k && a[st[k]]>a[i]) k--;if(k) rtree[st[k]]=i;if(k<top) ltree[i]=st[k+1];st[++k]=i;top=k;}dfs(st[1]); //从根开始搜索return 0;
}

(待填坑)【数据结构】笛卡尔树相关推荐

  1. ▲数据结构 笛卡尔树【2011】五2 C++版

    转载于:https://www.cnblogs.com/qilinart/articles/5940726.html

  2. hdu6305(笛卡尔树/分治)

    这道需要注意到一点..就是如果询问的区间如果覆盖了最大数,那么rmq一定是确定的..故以这个最大数为分界,左右2个区间是完全独立的..因此就可以采用分治的做法去做..聪明的汪聚聚已经实现.. 然后dl ...

  3. SGU155(笛卡尔树的构造)

    题目:http://acm.sgu.ru/problem.php?contest=0&problem=155 题意:给出每个点的两个值key和fix,且所有的key值和fix值都是不相同的,要 ...

  4. 笛卡尔树详解带建树模板及例题运用(Largest Submatrix of All 1’s,洗车 Myjnie,Removing Blocks,SPOJ PERIODNI)

    文章目录 笛卡尔树 介绍 例题 Largest Submatrix of All 1's 应用 「POI2015」洗车 Myjnie [AGC028B] Removing Blocks SPOJ PE ...

  5. YbtOJ#752-最优分组【笛卡尔树,线段树】

    正题 题目链接:http://www.ybtoj.com.cn/problem/752 题目大意 nnn个人,每个人有cic_ici​和did_idi​分别表示这个人所在的队伍的最少/最多人数. 然后 ...

  6. [集训队作业2018] count(笛卡尔树,生成函数,卡特兰数)

    传送门 什么情况下两序列同构 对于两序列A[1,n],B[1,n]A[1,n],B[1,n]A[1,n],B[1,n],设fA(1,n)=pa,fB(1,n)=pbf_A(1,n)=p_a,f_B(1 ...

  7. 笛卡尔树(Cartesian Tree)

    一.简介 笛卡尔树是一种特定的二叉树数据结构,由数组存储.在范围最值.范围top k查询方面广泛应用. 笛卡尔树的性质: 树中的元素满足二叉搜索树性质,要求按照中序遍历得到的序列为原数组序列 树中节点 ...

  8. 笛卡尔树简介(分类到treap里面)

    笛卡尔树结构由Vuillmin在解决范围搜索的几何数据结构问题时提出的,从数列中构造一棵笛卡尔树可以线性时间完成,需要采用基于栈的算法来找到在该数列中的所有最近小数.由此可知,笛卡尔树是一种特定的二叉 ...

  9. C++ 树进阶系列之笛卡尔树的两面性

    1. 前言 笛卡尔树是一种特殊的二叉树数据结构,融合了二叉堆和二叉搜索树两大特性.笛卡尔树可以把数列(组)对象映射成二叉树,便于使用笛卡尔树结构的逻辑求解数列的区间最值或区间排名等类似问题. 如有数列 ...

  10. [bzoj5042][笛卡尔树]LWD的分科岛

    Description 大家都知道在文理分科的时候总是让人纠结的,纠结的当然不只是自己.比如 YSY 就去读了文科, LWD 知道了很 气.于是他就去卡了 BZOJ 测评机, 晚上他做了一个谜一样的梦 ...

最新文章

  1. Ubuntu 彻底卸载 OpenCV
  2. 单例模式——懒汉模式(C++)
  3. mysql语句表_mysql表级sql语句
  4. java序列化和反序列化_Java恶意序列化背后的历史和动机
  5. java请求响应中转_J2EE中的请求中转、重定向和包含关系
  6. 《ArcGIS Runtime SDK for Android开发笔记》——问题集:使用TextSymbol做标注显示乱码...
  7. 数字后端基础技能之:CTS(中篇)
  8. 如何优化你的布局层级结构之RelativeLayout和LinearLayout及FrameLayout性能分析
  9. 【Android智能硬件开发】【010】安卓读写串口
  10. 在reader中勾选pdf复选框_Excel中设计具有可任意勾选复选框的操作方法
  11. python爬虫之JS混淆加密、字体反爬
  12. 2019年嵌入式前景如何?现在学习是否太晚?
  13. 小米手机微信无法连接到服务器1-1,小米1S系统版本低不能登录微信解决办法
  14. 计算机电子电路原理图,简易电子琴设计电路图大全(八款模拟电路设计原理图详解) - 消费类电子电路图...
  15. 一对一网络课堂教室应用教程实例
  16. 伯恩半导体 - ESD 选型指南
  17. JMeter 进行压力测试并发测试步骤,及文件上传并发测试演示
  18. 生成模型和判别模型学习
  19. 任何行业都能用上的名词(用于提升逼格)
  20. Activity + Fragment 页面重叠问题

热门文章

  1. CodeFroces gym 100781 A.Adjoin the Networks(贪心)
  2. 如何去掉百度地图 信息框的白色箭头
  3. TX-LCN事务控制原理
  4. Android体重档案代码,Android开发实现的标准体重计算器功能示例
  5. [渝粤教育] 南阳理工学院 英语漫话中国文化 参考 资料
  6. 数据分析——人口变化matplotilb绘图
  7. HBuilder制作表格式的简历
  8. 你不会因为实施了Scrum而变敏捷
  9. 基于银河麒麟 V10 系统安装和卸载 DM8 数据库
  10. 三角学常见公式定理证明