제출 #1173508

#제출 시각아이디문제언어결과실행 시간메모리
1173508SyriusCat Exercise (JOI23_ho_t4)C++20
100 / 100
510 ms105300 KiB
#include <bits/stdc++.h> using namespace std; #define int long long #define ll long long #define ff first #define ss second #define pint pair < int , int > #define fast ios_base::sync_with_stdio(NULL); cin.tie(NULL) typedef vector < int > vint; const int inf = 1e9 + 9; const int mxn = 2e5 + 2; const int mod = 1e9 + 7; const int lg = 20; vector < vint > adj(mxn); int n; int a[mxn] , p[mxn]; int lev[mxn] , tab[lg][mxn]; int in[mxn] , out[mxn]; int rev[mxn]; int timer = 0; void tour(int u , int par) { in[u] = ++timer; a[timer] = p[u]; rev[timer] = u; for (int v : adj[u]) { if (v == par) continue; tour(v , u); } out[u] = timer; } struct node { int tl , tm , tr; int id; bool lz; node *left , *right; node (int l , int r) { tl = l , tr = r , tm = (l + r) / 2; lz = 0; if (tl == tr) { id = tl; return; } left = new node(tl , tm); right = new node(tm+1 , tr); id = (a[left->id] > a[right->id]) ? left->id : right->id; } int querrrry(int l , int r) { if (tl == l && tr == r) return id; if (r <= tm) return left -> querrrry(l , r); else if (l > tm) return right -> querrrry(l , r); int idl = left -> querrrry(l , tm); int idr = right -> querrrry(tm+1 , r); return (a[idl] > a[idr]) ? idl : idr; } int query(int l , int r) { return rev[querrrry(l , r)]; } void pro() { if (lz == 0) return; left -> lz = right -> lz = 1; left -> id = right -> id = 0; lz = 0; } void update(int l , int r) { if (tl == l && tr == r) { lz = 1; id = 0; return; } pro(); if (r <= tm) left -> update(l , r); else if (l > tm) right -> update(l , r); else { left -> update(l , tm); right -> update(tm+1 , r); } id = (a[left->id] > a[right->id]) ? left->id : right->id; } } *root; void setlev(int u , int par , int lv) { lev[u] = lv; tab[0][u] = par; for (int v : adj[u]) { if (v == par) continue; setlev(v , u , lv+1); } } void build(int st) { setlev(st , st , 0); for (int i = 1; i < lg; i++) { for (int j = 1; j <= n; j++) { tab[i][j] = tab[i-1][tab[i-1][j]]; } } } int dis(int a , int b) { if (lev[b] < lev[a]) swap(a , b); int d = lev[b] - lev[a]; for (int i = 0; i < lg; i++) { if (d & (1 << i)) b = tab[i][b]; } if (a == b) return d; int ret = 0; for (int i = lg-1; i >= 0; i--) { if (tab[i][a] != tab[i][b]) { a = tab[i][a]; b = tab[i][b]; ret += (1 << i); } } return (ret + 1) * 2 + d; } int dfs(int u) { int ver = root -> query(in[u] , out[u]); if (ver == u) { root -> update(in[u] , in[u]); ver = root -> query(in[u] , out[u]); if (ver == 0) return 0; int result = 0; for (int v : adj[u]) { if (lev[v] < lev[u]) continue; result = max(result , dfs(v) + 1); } root -> update(in[u] , out[u]); return result; } // cout << u << ' ' << ver << '\n'; if (ver == 0) return 0; // cout << "CONTINUING " << u << ' ' << ver << '\n'; int ans = dfs(ver) + dis(u , ver); root -> update(in[ver] , out[ver]); // cout << "current answer is: " << ans << '\n'; int ret = dis(u , ver); while (1) { int newver = root -> query(in[u] , out[u]); // cout << "CURRENTLY AT u = " << u << " BUT NEWVER IS: " << newver << '\n'; if (newver == 0) break; ret += dis(ver , newver); // cout << "RET: " << ret << '\n'; ver = newver; // root -> update(in[ver] , in[ver]); ans = max(ans , ret + dfs(ver)); root -> update(in[ver] , out[ver]); // cout << "current answer is: " << ans << '\n'; } root -> update(in[u] , out[u]); return ans; } signed main() { cin >> n; int st = 1; for (int i = 1; i <= n; i++) { cin >> p[i]; if (p[i] == n) st = i; } for (int i = 0; i < n-1; i++) { int v , u; cin >> v >> u; adj[u].push_back(v); adj[v].push_back(u); } build(st); tour(st , st); a[0] = -inf; root = new node(0 , n); cout << dfs(st) << '\n'; return 0; }
#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...