link
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;
}