제출 #889632

#제출 시각아이디문제언어결과실행 시간메모리
889632vjudge1Tourism (JOI23_tourism)C++17
18 / 100
5090 ms44612 KiB
#include <bits/stdc++.h> using namespace std; #define ff first #define ss second #define all(a) a.begin(), a.end() const int mod = 998244353; const int N = 1e5; pair<int, int> chmax(pair<int, int> A, pair<int, int> B){ if(A.ff > B.ff) return A; return B; } pair<int, int> chmin(pair<int, int> A, pair<int, int> B){ if(A.ff > B.ff) return B; return A; } struct sparse{ vector<vector<pair<int, int> > > m_table; vector<vector<pair<int, int> > > ma_table; int n; sparse(int sz){ n = sz; m_table.resize(18); ma_table.resize(18); for(auto &i : m_table){ i.resize(sz); } for(auto &i : ma_table) i.resize(sz); }; void build(vector<pair<int, int>> &a){ for(int lg = 0; lg < 18; lg++){ for(int i = 0;i < n; i++){ if(lg == 0){ m_table[lg][i] = a[i]; ma_table[lg][i] = a[i]; }else{ int k = 1<<(lg-1); m_table[lg][i] = chmin(m_table[lg-1][i], m_table[lg-1][min(n - 1, i + k)]); ma_table[lg][i] = chmax(ma_table[lg-1][i], ma_table[lg-1][min(n - 1, i + k)]); } } } } pair<int, int> get_max(int l, int r){ int k = __lg(r-l+1); return chmax(ma_table[k][l], ma_table[k][r-(1<<k) + 1]); } pair<int, int> get_min(int l, int r){ int k = __lg(r-l+1); return chmin(m_table[k][l], m_table[k][r-(1<<k) + 1]); } }; vector<int> g[N+1]; int depth[N+1], c[N+1]; int timer=1; int tin[N+1], tout[N+1]; int up[N+1][18]; int n, m, q; void dfs(int v, int par){ up[v][0] = par; tin[v] = timer++; for(int i = 1;i < 18; i++){ up[v][i] = up[up[v][i-1]][i-1]; } for(int to : g[v]){ if(to == par) continue; depth[to] = depth[v] + 1; dfs(to, v); } tout[v] = timer++; } int lca(int a, int b){ if(depth[a] > depth[b]) swap(a, b); int k = depth[b] - depth[a]; for(int i = 0;i < 18; i++){ if(k & (1<<i)){ b = up[b][i]; } } if(a == b) return a; for(int i = 17; i >= 0; i--){ if(up[a][i] != up[b][i]){ a = up[a][i]; b = up[b][i]; } } return up[a][0]; } int vert; vector<int> vec; int in_subtree(int v){ int it = lower_bound(all(vec), tin[v]) - vec.begin(); if(it < (int)vec.size() && vec[it] <= tout[v]) return 1; return 0; } void ans(int v, int par){ if(!in_subtree(v)) return; vert++; for(int to : g[v]){ if(to == par) continue; ans(to, v); } } signed main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> m >> q; int bambo = 1; for(int i = 1;i < n; i++){ int a, b; cin >> a >> b; if(a != i || b != a+1) bambo = 0; g[a].push_back(b); g[b].push_back(a); } for(int i = 0;i < m; i++){ cin >> c[i]; } dfs(1, 1); vector<pair<int, int> > vals; for(int i = 0;i < m; i++){ vals.push_back(make_pair(tin[c[i]], c[i])); } sparse table(m); table.build(vals); if(bambo){ while(q--){ int l, r; cin >> l >> r; l--, r--; int mn = table.get_min(l, r).ss; int mx = table.get_max(l, r).ss; cout << depth[mn] - depth[mx] + 1 << '\n'; } return 0; } while(q--){ int l, r; cin >> l >> r; l--, r--; int mn = c[l], mx = c[l]; vec.clear(); for(int i = l;i <= r; i++){ vec.push_back(tin[c[i]]); if(tin[mn] > tin[c[i]]){ mn = c[i]; } if(tin[mx] < tin[c[i]]){ mx = c[i]; } } mn = table.get_min(l, r).ss; mx = table.get_max(l, r).ss; sort(all(vec)); vec.erase(unique(all(vec)), vec.end()); vert = 0; int lc = lca(mn, mx); ans(lc, up[lc][0]); cout << vert << '\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...