笛卡尔树

概念

Link

笛卡尔树的节点各有两个权值,其中一个权值满足二叉搜索树的性质,另一个满足小(大)根堆的性质。

所以说 Treap 也是一种笛卡尔树

构造

知乎

以下均假设原序列元素两两不相同。

从左至右依次加入元素,维护当前笛卡尔树的右儿子链

rootrsonrson.rsonrson.rson.rson

至一个栈内。

设加入的节点为 xt 为当前笛卡尔树。

  1. 找到栈中最靠顶部的节点 y 使得 val[y]<val[x]

  2. 特判 y 为栈顶,直接 t[y].rson:=x 即可结束。

  3. 记栈中 y 的楼上为 zt[y].rson:=x,t[x].lson:=z

  4. 将栈中 y 之上的所有全部 pop,再 push(x)

时间 O(n)

实战

模板

好像单调栈能做的,她都行。

P5854 【模板】笛卡尔树

以前这里贴了一个 O(nlogn) 的代码,放了好久,我该咋办。

现在改好了,O(n) 的。

/*
* Author: ShaoJia
* Last Modified time: 2022-09-27 18:20:41
* Motto: We'll be counting stars.
*/
#include<bits/stdc++.h>
using namespace std;
#define For(i,j,k) for(int i=(j),i##_=(k);i<=i##_;i++)
#define ll long long
#define N 10000005
char buf[1<<21],*p1,*p2;
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
inline int read() {
int x=0,f=1;
char c=gc();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=gc();}
return x*f;
}
int n,a[N],ls[N],rs[N],s[N],st;
signed main(){
n=read();
For(i,1,n) a[i]=read();
s[st=1]=1;
int x;
For(i,2,n){
if(a[i]>a[s[st]]){
rs[s[st]]=i;
s[++st]=i;
}else if(a[i]<a[s[1]]){
ls[i]=s[1];
s[st=1]=i;
}else{
x=s[st--];
while(a[s[st]]>a[i]){
x=s[st--];
}
rs[s[st]]=i;
ls[i]=x;
s[++st]=i;
}
}
// For(i,1,n) cout<<ls[i]<<" "; cout<<"\n";
// For(i,1,n) cout<<rs[i]<<" "; cout<<"\n";
ll L=0,R=0;
For(i,1,n){
L^=1ll*i*(ls[i]+1);
R^=1ll*i*(rs[i]+1);
}
cout<<L<<" "<<R<<"\n";
return 0;}

CF1220F Gardener Alex

vp 场上 O(n) 想法因为 sb 错误没调出来,被 Little09 O(nlogn) 压哨过暴踩。

发现其实就是要快速求出一个序列的任意前缀的笛卡尔树的深度。

发现我们可以直接在右链上维护每个节点左儿子的 mxdep,压栈和弹栈的时候维护一下即可。

细节看代码吧,讲不清楚 /yun。

Link

P5654 基础函数练习题

咕咕咕,我还没 A 这道题呢。

P7244 章节划分

过了,但是咕咕咕。

CF1748E Yet Another Array Counting Problem

由于最大值位置定义为最左边的最大值,我们将每个位置 i 上的值改成二元组 (val,i),这样不存在相同的元素了,大小直接用 std::pair 比较即可。

不难发现题目相当于要求与 {a} 大根笛卡尔树结构相同的(长度 n,值域 m)序列有多少个。

然后就简单了,发现 nm106,树形背包做完了。

Code

posted @   ShaoJia  阅读(74)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示