题目链接:https://ac.nowcoder.com/acm/contest/368/B
题意
题解
首先把第二个条件倒过来变成如果在右子树中选一个点,在左子树中选的点都要比它大,这样就相当于 根 < 右子树 < 左子树。可以按照这个顺序搞出一个dfs序列,然后在上面做LIS即可。
二分优化LIS: dp[i]表示长度为i的上升子序列的最后一位数最小是多少。
代码
//https://ac.nowcoder.com/acm/contest/368/B
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
const int maxn = 2e5+5;
vector<int> G[maxn];
int w[maxn],son[2][maxn],dp[maxn];
int a[maxn];
int p;
void dfs(int u) {
if(u == 0)
return;
a[p++] = w[u];
dfs(son[1][u]);
dfs(son[0][u]);
}
void solve() {
dp[0] = a[0];
int cnt = 0;
for(int i = 1; i < p; ++i) {
if(a[i] > dp[cnt]) dp[++cnt] = a[i];
else {
int pos = int(lower_bound(dp,dp+cnt+1,a[i])-dp);
dp[pos] = a[i];
}
}
cout << cnt+1 << endl;
}
int main() {
int n;
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
scanf("%d", &w[i]);
}
for(int i = 1; i <= n; ++i) {
for(int j = 0; j < 2; ++j) {
int u;
scanf("%d", &u);
if(u) {
son[j][i] = u;
}
}
}
dfs(1);
solve();
return 0;
}