快来踩爆这个蒟蒻吧|

Little_corn

园龄:1年1个月粉丝:10关注:17

2024-04-25 12:59阅读: 11评论: 0推荐: 0

笛卡尔树

笛卡尔树实际上就是对于多个二元组 (ki,wi) 的一棵树,使其所有 k 值满足二叉搜索树的性质,且所有 w 值都满足小根堆的性质。

在构建时,对于右链上的元素,自底向上一定是 w 值由小到大的,且一定 k 值从小到大。

所以我们按 k 值从小到大排序,比并按顺序插入右链中。

假设我们轮到第 i 个元素插入,我们先找到在第一个右链中 w 值大于 wi 的元素下标 j 。因为这棵树需要满足二叉搜索树的性质,所以我们将 j 以下的元素接到 i 的左子树上,并将 i 接到 j 的右子树上。

使用栈模拟即可。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e7+10;
int n;
int st[N],top;
int p[N],ls[N],rs[N];
inline int read(){
int x=0;
char c='&';
while(!isdigit(c))c=getchar();
while(isdigit(c)){
x=x*10+c-'0';
c=getchar();
}
return x;
}
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
n=read();
// cout<<n<<endl;
for(int i=1;i<=n;i++)p[i]=read();
for(int i=1;i<=n;i++){
int k=top;
while(k>0&&p[st[k]]>p[i])k--;
if(k)rs[st[k]]=i;
if(k<top)ls[i]=st[k+1];
top=k;
st[++top]=i;
}
int ans1=0,ans2=0;
for(int i=1;i<=n;i++){
ans1=ans1^(i*(ls[i]+1));
ans2=ans2^(i*(rs[i]+1));
}
cout<<ans1<<" "<<ans2;
return 0;
}

本文作者:Little_corn

本文链接:https://www.cnblogs.com/little-corn/p/18157428

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Little_corn  阅读(11)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起