제출 #891760

#제출 시각아이디문제언어결과실행 시간메모리
891760abysmalCat Exercise (JOI23_ho_t4)C++14
100 / 100
755 ms68460 KiB
#include<iostream> #include<stdio.h> #include<stdint.h> #include<vector> #include<algorithm> #include<utility> #include<set> #include<map> #include<queue> #include<stack> #include<iomanip> #include<string> #include<math.h> #include<assert.h> using namespace std; const double PI = (double) atan(1.0) * 4; const int64_t INF = (int64_t) 1e18 + 777; const int64_t mINF = (int64_t) 2e9 + 777; const int64_t offset = (int64_t) 1e6 + 777; const int64_t MOD = 1e9 + 7; const int nbit = 11; const int ndig = 10; const int nchar = 26; const int p1 = 31; const int p2 = 53; const int D = 4; int dr[D] = {0, 1, 0, -1}; int dc[D] = {1, 0, -1, 0}; // 0 right // 1 down // 2 left // 3 up int modadd(int t1, int t2) { int res = t1 + t2; if(res >= MOD) res -= MOD; return res; } int modmul(int t1, int t2) { int64_t res = 1LL * t1 * t2; return (res % MOD); } struct LCA { int n; int t; int LOG; vector<int> f; vector<int> pos; vector<int> depth; vector<vector<int> > rmq; vector<vector<int> > adj; LCA(int n_) { n = n_; t = 0; LOG = 0; f.resize(n, -1); adj.resize(n); depth.resize(n, 0); } void prep() { DFS(); while((1 << LOG) <= t) LOG++; rmq.resize(LOG, vector<int>(t, 0)); for(int i = 0; i < t; i++) { rmq[0][i] = pos[i]; } for(int i = 1; i < LOG; i++) { for(int j = 0; j + (1 << i) - 1 < t; j++) { int d1 = depth[ rmq[i - 1][j] ]; int d2 = depth[ rmq[i - 1][j + (1 << (i - 1))] ]; if(d1 < d2) rmq[i][j] = rmq[i - 1][j]; else rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))]; } } } int getLCA(int i, int j) { i = f[i]; j = f[j]; if(i > j) swap(i, j); int len = j - i + 1; int bt = 31 - __builtin_clz(len); if(depth[ rmq[bt][i] ] < depth[ rmq[bt][j - (1 << bt) + 1] ]) return rmq[bt][i]; return rmq[bt][j - (1 << bt) + 1]; } int dis(int u, int v) { int x = getLCA(u, v); return depth[u] + depth[v] - 2 * depth[x]; } void addEdge(int u, int v) { adj[u].push_back(v); adj[v].push_back(u); } void DFS(int u = 0, int p = -1) { f[u] = t++; pos.push_back(u); for(int i = 0; i < (int) adj[u].size(); i++) { int v = adj[u][i]; if(v == p) continue; depth[v] = depth[u] + 1; DFS(v, u); pos.push_back(u); t++; } } }; struct Solution { int n; vector<int> a; vector<int> ver; vector<int> link; vector<int> size; vector<vector<int> > adj; Solution() {} void solve() { cin >> n; a.resize(n); ver.resize(n, -1); LCA lca(n); adj.resize(n); for(int i = 0; i < n; i++) { cin >> a[i]; a[i]--; ver[a[i]] = i; } for(int i = 0; i < n - 1; i++) { int u; int v; cin >> u >> v; u--; v--; lca.addEdge(u, v); adj[u].push_back(v); adj[v].push_back(u); } lca.prep(); link.resize(n); for(int i = 0; i < n; i++) { link[i] = i; } vector<int64_t> dp(n, 0); for(int i = 0; i < n; i++) { int u = ver[i]; for(int j = 0; j < (int) adj[u].size(); j++) { int v = adj[u][j]; if(a[v] > a[u]) continue; int x = find(v); dp[u] = max(dp[u], dp[x] + lca.dis(u, x)); unite(u, x); } } cout << dp[ver[n - 1]] << "\n"; } int find(int x) { while(x != link[x]) { x = link[x]; } // cerr << "c = " << c << "\n"; return x; } void unite(int x, int y) { y = find(y); link[y] = x; } int modsub(int t1, int t2) { int res = t1 - t2; if(res < 0) res += MOD; return res; } bool BIT(int& mask, int& j) { return (mask & MASK(j)); } int64_t Abs(int64_t t1) { if(t1 < 0) return -t1; return t1; } int MASK(int j) { return (1 << j); } }; void __startup() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); } int main() { __startup(); int t = 1; // cin >> t; for(int i = 1; i <= t; i++) { Solution().solve(); } 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...