笛卡尔树模板
笛卡尔树模板
时间复杂度:\(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;
}

浙公网安备 33010602011771号