P5854 【模板】笛卡尔树 题解

P5854 【模板】笛卡尔树

sol

因为考试涉及到了笛卡尔树,所以我来看一下

其实笛卡尔树本质上就是一颗 \(Treap\)

主要关注这么建树

维护一个递增的单调栈,枚举到 \(i\)

  • 假设单调栈中最大的比 \(a[i]\) 小的叫 \(fa\) ,那么 \(i\) 肯定是 \(fa\) 的右儿子

  • 假设单调栈中最小的比 \(a[i]\) 大的叫 \(son\),那么 \(son\) 肯定是 \(i\) 的左儿子

code

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
inline int read(){
	int ret=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
	return ret*f;
}
const int maxn=1e7+5;
int N,a[maxn],st[maxn],ls[maxn],rs[maxn];
LL L,R;
int main(){
	N=read();
	for(int i=1,pos=0,top=0;i<=N;i++){
		a[i]=read();
		pos=top;
		while(pos&&a[st[pos]]>a[i])pos--;
		if(pos)rs[st[pos]]=i;
		if(pos<top) ls[i]=st[pos+1];
		st[top=++pos]=i;
	}
	for(int i=1;i<=N;i++) L^=1ll*i*(ls[i]+1),R^=1ll*i*(rs[i]+1);
	printf("%lld %lld\n",L,R);
	return 0;
}
posted @ 2021-11-16 19:30  Martian148  阅读(59)  评论(0编辑  收藏  举报