📚【模板】笛卡尔树

笛卡尔树是一种二叉树,每个节点 \(i\)\(\left(k_i,w_i\right)\) 构成, 其中,\(k\) 满足BST 的性质,\(w\) 满足堆的性质。

  • \(k,w\) 互不相同,则构成的笛卡尔树唯一;

  • 两个点的 \(LCA\) 即它们的 \(RMQ\)


构建一颗笛卡尔树,先以 \(k\) 为序排序,再维护一条右链。(@虚树)


\(\textrm{luogu P5854 【模板】笛卡尔树}\)

#include <stdio.h>
#define llt long long int
const int N = 1e7+10;
int n, p[N];
int stk[N], top;
int rid[N], lid[N];
llt lans, rans;
void cts() {
	for(int i = 1, k = 0;i <= n;++i) {
		while(k&&p[stk[k]] > p[i]) 
			--k;
		if(k) 
			rid[stk[k]] = i;
		if(k < top) 
			lid[i] = stk[k+1];
		stk[++k] = i;
		top = k;
	}
}
signed main() {
	get_int(n);
	for(int i = 1;i <= n;++i) 
		get_int(p[i]);
	cts();
	for(int i = 1;i <= n;++i) {
		lans ^= i*(lid[i]+1LL);
		rans ^= i*(rid[i]+1LL);
	}
	printf("%lld %lld\n",lans,rans);
	return 0;
}

ps:本题卡常,请使用较快的读入方式

posted @ 2022-08-14 14:35  bikuhiku  阅读(80)  评论(0编辑  收藏  举报