Submission #769233

#TimeUsernameProblemLanguageResultExecution timeMemory
769233danikoynovCat Exercise (JOI23_ho_t4)C++14
21 / 100
238 ms19576 KiB
#include<bits/stdc++.h> #define endl '\n' using namespace std; typedef long long ll; void speed() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); } const int maxn = 2e5 + 10; int n, a[maxn], used[maxn], dp[maxn], pos[maxn]; vector < int > adj[maxn]; int rec(int val) { if (used[val]) return dp[val]; used[val] = 1; int left = 0, right = n + 1; for (int i = n; i > val; i --) { if (pos[i] > pos[val]) { right = min(right, pos[i]); } else { left = max(left, pos[i]); } } int mx = -1; for (int i = pos[val] + 1; i < right; i ++) { if (a[i] > mx) { mx = a[i]; dp[val] = max(dp[val], i - pos[val] + rec(a[i])); } } mx = -1; for (int i = pos[val] - 1; i > left; i --) { if (a[i] > mx) { mx = a[i]; dp[val] = max(dp[val], pos[val] - i + rec(a[i])); } } return dp[val]; } int dfs(int v, int p, int mx, int dis, int val) { if (mx > val) return 0; int ans = 0; if (a[v] == mx) ans = max(ans, dis + dp[v]); for (int u : adj[v]) { if (u == p) continue; ans = max(ans, dfs(u, v, max(mx, a[u]), dis + 1, val)); } return ans; } int bef[maxn], aft[maxn]; pair < int, int > tree[4 * maxn]; void build_tree(int root, int left, int right) { if (left == right) { tree[root] = {a[left], left}; return; } int mid = (left + right) / 2; build_tree(root * 2, left, mid); build_tree(root * 2 + 1, mid + 1, right); tree[root] = max(tree[root * 2], tree[root * 2 + 1]); } pair < int, int > query(int root, int left, int right, int qleft, int qright) { if (left > qright || right < qleft) return {-1, -1}; if (left >= qleft && right <= qright) return tree[root]; int mid = (left + right) / 2; return max(query(root * 2, left, mid, qleft, qright), query(root * 2 + 1, mid + 1, right, qleft, qright)); } void solve() { cin >> n; for (int i = 1; i <= n; i ++) { cin >> a[i]; pos[a[i]] = i; } for (int i = 1; i < n; i ++) { int v, u; cin >> v >> u; adj[v].push_back(u); adj[u].push_back(v); } /**if (n <= 5000) { for (int i = 1; i <= n; i ++) { int v = pos[i]; for (int u : adj[v]) { dp[v] = max(dp[v], dfs(u, v, a[u], 1, a[v])); } ///cout << v << " : " << dp[v] << endl; } cout << dp[pos[n]] << endl; } else*/ { stack < int > st; for (int i = 1; i <= n; i ++) { while(!st.empty() && a[st.top()] < a[i]) st.pop(); if (!st.empty()) bef[i] = st.top(); ///cout << "stack " << i << " " << st.top() << endl; st.push(i); } while(!st.empty()) st.pop(); for (int i = n; i > 0; i --) { while(!st.empty() && a[st.top()] < a[i]) st.pop(); if (!st.empty()) aft[i] = st.top(); else aft[i] = n + 1; st.push(i); } build_tree(1, 1, n); for (int i = 1; i <= n; i ++) { int v = pos[i]; ///cout << "now " << v << " " << bef[v] << " " <<aft[v] << endl; pair < int, int > lf = query(1, 1, n, bef[v] + 1, v - 1); pair < int, int > rf = query(1, 1, n, v + 1, aft[v] - 1); ///cout << v << " " << lf.second << " " << rf.second << endl; if (lf.first != -1) { ///cout << "here " << dp[lf.first] << " " << lf.first << endl; dp[v] = max(dp[v], dp[lf.second] + v - lf.second); } if (rf.first != -1) dp[v] = max(dp[v], dp[rf.second] + rf.second - v); //cout << dp[v] << endl; } cout << dp[pos[n]] << endl; } } int main() { solve(); return 0; } /** 5 5 3 2 1 4 1 2 2 3 3 4 4 5 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...