笛卡尔树模板

题目

笛卡尔树模板

时间复杂度:\(O(n)\)

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+10;
int n,p[N],stk[N];
long long ql,qr,l[N],r[N];
void build(){//满足BST和堆性质
	int top=0,cur=0;
	for(int i=1;i<=n;i++){
		while(top&&p[stk[top]]>p[i]) top--; //弹出所有权值大于当前节点权值的栈顶元素,维护栈的单调性(小根堆)
		if(top) r[stk[top]]=i;//如果栈中还有元素,则当前节点i成为栈顶元素的右儿子
		if(top<cur) l[i]=stk[top+1];//如果栈顶指针小于上一次的栈顶(即发生了弹出),则弹出部分的第一个节点(下标最大)成为i的左儿子(stk[top+1]是最后一个被弹出的节点)
		stk[++top]=i;
		cur=top;
	}
}
int main(){
	ios::sync_with_stdio(0);cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>p[i];
	}
	build();
	for(int i=1;i<=n;i++){
		ql^=i*(l[i]+1);
		qr^=i*(r[i]+1);
	}
	cout<<ql<<' '<<qr;
	return 0;
}
posted @ 2026-08-09 19:34  decentz  阅读(15)  评论(0)    收藏  举报