分析

我们可以发现一个特征:
左子树的值当前点值右子树的值
这个可以让我们联想到dfn序!
随着dfs的进行
我们先走完左子树,再走完右子树,最后离开当前节点
发现是一个后序遍历的dfn序
拉出来之后
我们只需要进行一个最长不上升子序列的求解即可
树状数组离散化之后维护一下就OK了
时间复杂度:
期望得分:100分

代码

//Nowcoder 22494
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

#define ll long long
#define cl(x, y) memset((x), (y), sizeof(x))
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define per(i, a, b) for(int i = a; i >= b; i--)
#define de(x) cerr << #x << " = " << x << " "
#define inc_mod(x, y) x = ((x - y) % mod + mod) % mod
#define add_mod(x, y) x = (x + y) % mod
#define lowbit(x) (x & (-x))
#define inf 0x3f3f3f3f
#define mod 998244353
#define rson (x << 1 | 1)
#define lson (x << 1)
using namespace std;
const int maxn = 1e5 + 10;

int val[maxn], num[maxn], cop[maxn];
int dfn[maxn], dfn_num, fro[maxn];
int ans, u, v, w, opt, total;
int child[maxn][2];

inline void file() {
    freopen(".in", "r", stdin);
    freopen(".out", "w", stdout);
}

inline void dfs(int now, int pre) {
    if(child[now][0]) dfs(child[now][0], now);
    if(child[now][1]) dfs(child[now][1], now);
    dfn[now] = ++dfn_num;
    num[dfn_num] = val[now];
}

inline void update(int now, int temp) { while(now <= maxn - 5) { fro[now] = max(fro[now], temp); now += lowbit(now); } }
inline int get(int now) { int res = 0; while(now) { res = max(res, fro[now]); now -=lowbit(now); } return res; }

int main() {
    // file();
    ios::sync_with_stdio(false);
    cin >> total;
    rep(i, 1, total) cin >> val[i], cop[i] = val[i];
    sort(cop + 1, cop + total + 1);
    int size = unique(cop + 1, cop + total + 1) - (cop + 1);
    rep(i, 1, total) val[i] = lower_bound(cop + 1, cop + size + 1, val[i]) - cop;
    rep(i, 1, total) cin >> child[i][0] >> child[i][1];
    dfs(1, 0);
    per(i, total, 1) {
        int temp = get(num[i] - 1);
        ans = max(ans, temp + 1);
        update(num[i], temp + 1);
    }
    cout << ans << endl;
    // fclose(stdin);
    // fclose(stdout);
    system("pause");
    return 0;
}