【二分】Codeforces Round 279 (Div. 2) F. Treeland Tour (树上最长上升子序列)
2021-08-09 20:14:00
# ACM
题链
题意如题
首先得知道最长上升子序列如何在O(nlogn)内求出;
参考【二分】AcWing 2978. 最长上升子序列
那么对于每一个点作为根节点跑一遍最长上升子序列算法即可,复杂度$O(n^2logn)$;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 #include <bits/stdc++.h> using namespace std; #define LL long long #define ls rt<<1 #define rs rt<<1|1 #define eps 1e-9 #define mod 1000000007 #define MAXN 2e9 #define MS 100005 int n,m;vector<int > vc[MS]; int a[MS];int p[MS];int ans;void dfs (int u,int f) { int pos = lower_bound (p+1 ,p+n+1 ,a[u]) - p; int tmp = p[pos]; p[pos] = a[u]; ans = max (ans,pos); for (auto v:vc[u]){ if (v != f) dfs (v,u); } p[pos] = tmp; } void solve () { cin >> n; for (int i=1 ;i<=n;i++) cin >> a[i]; for (int i=2 ;i<=n;i++){ int u,v; cin >> u >> v; vc[u].push_back (v); vc[v].push_back (u); } for (int i=1 ;i<=n;i++) p[i] = MAXN; for (int i=1 ;i<=n;i++){ dfs (i,0 ); } cout << ans << "\n" ; } int main () { ios::sync_with_stdio (false ); int ce; ce = 1 ; while (ce--){ solve (); } return 0 ; }
2021-08-09 20:14:00
# ACM