树上求最大上升子序列 Login - Codeforces
##C<https://codeforces.com/gym/489511/problem/C>
##思路
**最大上升子序列+用链式前向星存搜多叉树**
**借鉴大佬的代码 一开始傻傻的每个点跑一次dfs查路径 最大上升子序列也难求 注意区分字串和子序列 子序列可跳点**
##代码
```cpp
#include<bits/stdc++.h>
using namespace std;
int n;
int a[100005];
int head[100005];//以i为起点的最后一条边的编号
int cnt;
struct ad {
int from;
int to;
}e[200005];//双向边
void add(int x, int y) {
cnt++;
e[cnt].from = head[x];
e[cnt].to = y;
head[x] = cnt;
}
int ans[100005];//dfs时记录答案
int s[100005];//最大上升子序列 维护
int l;//维护数组的尾巴
void dfs(int t, int f) {
int ops = lower_bound(s + 1, s + l + 1,a[t]) - s;//新进来一个数 贪心地加入它
int tmp = s[ops];//记录 用于回溯
s[ops] = a[t];
int fg = 0;//也是记录用于回溯
if (ops == l + 1) {//正好加在最后
l++;
fg = 1;
}
ans[t] = l;//最长就在尾巴
for (int i = head[t]; i; i = e[i].from) {
int t1 = e[i].to;//遍历这一层 以t为起点的边
if (t1 == f) continue;//回边
dfs(t1, t);
}
if (fg == 1) l--;//这一层搜完了 往上面回溯 恢复改变量
s[ops] = tmp;//恢复
}
int main()
{
cin >> n;
for (int i = 2; i <= n; i++) {
int x;
cin >> x;
add(i, x), add(x, i);
}
for (int i = 1; i <= n; i++) cin >> a[i];
dfs(1, 0);
for (int i = 2; i <= n; i++) cout << ans[i] << " ";
return 0;
}
```