P5854 【模板】笛卡尔树
题目描述
给定一个 \(1 \sim n\) 的排列 \(p\),构建其笛卡尔树。
即构建一棵二叉树,满足:
- 每个节点的编号满足二叉搜索树的性质。
- 节点 \(i\) 的权值为 \(p_i\),每个节点的权值满足小根堆的性质。
输入格式
第一行一个整数 \(n\)。
第二行一个排列 \(p_{1 \dots n}\)。
输出格式
设 \(l_i,r_i\) 分别表示节点 \(i\) 的左右儿子的编号(若不存在则为 \(0\))。
一行两个整数,分别表示 \(\operatorname{xor}_{i = 1}^n i \times (l_i + 1)\) 和 \(\operatorname{xor}_{i = 1}^n i \times (r_i + 1)\)。
输入输出样例 #1
输入 #1
5
4 1 3 2 5
输出 #1
19 21
说明/提示
【样例解释】
| \(i\) | \(l_i\) | \(r_i\) |
|---|---|---|
| \(1\) | \(0\) | \(0\) |
| \(2\) | \(1\) | \(4\) |
| \(3\) | \(0\) | \(0\) |
| \(4\) | \(3\) | \(5\) |
| \(5\) | \(0\) | \(0\) |
【数据范围】
对于 \(30\%\) 的数据,\(n \le 10^3\)。
对于 \(60\%\) 的数据,\(n \le 10^5\)。
对于 \(80\%\) 的数据,\(n \le 10^6\)。
对于 \(90\%\) 的数据,\(n \le 5 \times 10^6\)。
对于 \(100\%\) 的数据,\(1 \le n \le 10^7\)。
题解
#include <bits/stdc++.h>
using namespace std;
const int N=1e7+10;
typedef long long ll;
int n;
ll a[N];
ll sl[N],sr[N];
ll stk[N];
int top = 0;
void build()
{
for(int i=1;i<=n;i++)
{
int pos = top;
while(pos>0&&a[stk[pos]]>a[i])
{
pos--;
}
if(pos>0)sr[stk[pos]]=i;
if(pos<top)sl[i] = stk[pos+1];
stk[++pos] = i;
top = pos;
}
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
build();
ll res1=0,res2=0;
for(ll i=1;i<=n;i++)
{
res1 ^= i*(sl[i]+1);
res2 ^= i*(sr[i]+1);
}
cout<<res1<<' '<<res2<<'\n';
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t=1;
// cin>>t;
while(t--)
{
solve();
}
return 0;
}

浙公网安备 33010602011771号