首页 > 其他分享 >笛卡尔树

笛卡尔树

时间:2022-10-23 16:33:08浏览次数:65  
标签:结点 ch 右链 val 笛卡尔 权值

笛卡尔树

1.权值 \(\text{pos}\) 满足二叉搜索树的性质,通常用序列的下标作为权值;
2.权值 \(\text{val}\) 满足二叉堆的性质。

实现方法

我们考虑将元素按照键值 \(k\) 排序。然后一个一个插入到当前的笛卡尔树中。那么每次我们插入的元素必然在这个树的右链(右链:即从根结点一直往右子树走,经过的结点形成的链)的末端。于是我们执行这样一个过程,从下往上比较右链结点与当前结点 \(u\) 的 \(w\),如果找到了一个右链上的结点 \(x\) 满足 \(x_w<u_w\),就把 \(u\) 接到 \(x\) 的右儿子上,而 \(x\) 原本的右子树就变成 \(u\) 的左子树。

具体如图所示,图中红框部分就是我们始终维护的右链:

显然每个数最多进出右链一次(或者说每个点在右链中存在的是一段连续的时间)。这个过程我们可以用栈维护,栈中维护当前笛卡尔树的右链上的结点。一个点不在右链上了就把它弹掉。这样每个点最多进出一次,复杂度 \(O(n)\)。

典型例题

P5854 笛卡尔树

笛卡尔树模板题。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e7+5;
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(isdigit(ch))
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
struct node
{
    int l,r,pos,val;
}e[MAXN];
int n;
int s[MAXN],top;
int main()
{
    n=read();
    for(register int i=1;i<=n;i++)
    {
        e[i].val=read();
        e[i].l=e[i].r=0;
        e[i].pos=i;
    }
    for(register int i=1;i<=n;i++)
    {
        int k=top;
        while(k>0&&e[s[k]].val>e[i].val)k--;
        if(k)e[s[k]].r=i;
        if(k<top)e[i].l=s[k+1];
        s[++k]=i;
        top=k;
    }
    long long ans1=0,ans2=0;
    for(register int i=1;i<=n;i++)
    {
        ans1^=(long long)i*(e[i].l+1);
        ans2^=(long long)i*(e[i].r+1);
    }
    printf("%lld %lld",ans1,ans2);
    return 0;
}

标签:结点,ch,右链,val,笛卡尔,权值
From: https://www.cnblogs.com/yhx-error/p/16818825.html

相关文章

  • P5854 【模板】笛卡尔树
    题目链接P5854【模板】笛卡尔树题目描述给定一个\(1\simn\)的排列\(p\),构建其笛卡尔树。即构建一棵二叉树,满足:每个节点的编号满足二叉搜索树的性质。节点\(i......
  • 笛卡尔树
    在我的心里NOI大纲内提高级最难的知识点是圆方树、平衡树和笛卡尔树,平衡树自从自学了DHQ-treap后倒是有所改观,今天又重学笛卡尔树,发现貌似并不是那么难(原理上)。看来是......
  • kruskal重构树and笛卡尔树
    为什么放在了一起因为我个人旗帜鲜明的认为这是一个东西前者可以旗帜鲜明的解决图上(包括树上)限定最值的联通问题建立方式:跑kruskal时每连接两个点时建立一个新点把原......
  • 笛卡尔树
    概念Link笛卡尔树的节点各有两个权值,其中一个权值满足二叉搜索树的性质,另一个满足小(大)根堆的性质。所以说Treap也是一种笛卡尔树。构造知乎以下均假设原序列元素......
  • 笛卡尔树
    笛卡尔树是一种二叉树,每个节点有两个键值\(x,y\),一个满足BST,一个满足堆。上图:一个性质是如果键值确定那么笛卡尔树是唯一的。笛卡尔树如果暴力构造很简单:找到整个序列......
  • 通过迭代工具itertools.product快速得到多列表笛卡尔积(列表组合)
    1.核心代码importitertoolssubject=['我想','我要']action=['打开','关闭']target=['电视','冰箱','洗衣机']forresinitertools.product(subject,ac......
  • python itertools库 itertools.product() 用法 产生多个序列的笛卡尔积
    python itertools.product()用来产生多个序列的笛卡尔积,参数可两个或者多个序列,元组tulple,列表list,range生成的序列,集合set都可作为参数1importitertools2#par......
  • 【模板】笛卡尔树
    笛卡尔树是一种二叉树,每个节点\(i\)由\(\left(k_i,w_i\right)\)构成,其中,\(k\)满足BST的性质,\(w\)满足堆的性质。若\(k,w\)互不相同,则构成的笛卡尔树唯一;两......