Submission #492326

#TimeUsernameProblemLanguageResultExecution timeMemory
492326Vladth11Pictionary (COCI18_pictionary)C++14
126 / 140
285 ms65536 KiB
#include <bits/stdc++.h> #define debug(x) cerr << #x << " " << x << "\n" #define debugs(x) cerr << #x << " " << x << " " using namespace std; typedef long long ll; typedef pair <int, int> pii; const int NMAX = 100001; const int nr_of_bits = 14; int n, m, q; vector <int> divs[NMAX]; struct edge{ int from, to, cost; }; vector <edge> edges; void addEdge(int a, int b, int c){ edges.push_back({a, b, c}); edges.push_back({a, b, c}); } bool cmp(edge a, edge b){ return a.cost < b.cost; } int p[2 * NMAX]; int cnt[2 * NMAX]; int root(int x){ if(p[x] == x) return x; return p[x] = root(p[x]); } vector <pii> v[2 * NMAX]; void unite(int a, int b, int cost){ if(root(a) == root(b)) return; v[a].push_back({b, cost}); v[b].push_back({a, cost}); a = root(a); b = root(b); if(cnt[a] < cnt[b]) swap(a, b); p[b] = a; cnt[a] += cnt[b]; } int dp[NMAX * 2][nr_of_bits + 1]; int cost[NMAX * 2][nr_of_bits + 1]; pii timp[2 * NMAX]; int stamp; bool isParent(int a, int b){ return (timp[a].first <= timp[b].first && timp[b].second <= timp[a].second); } void DFS(int node, int p){ dp[node][0] = p; timp[node].first = ++stamp; for(auto x : v[node]){ if(x.first == p) continue; cost[x.first][0] = x.second; DFS(x.first, node); } timp[node].second = ++stamp; } int LCA(int a, int b){ int r = a, pas = nr_of_bits; while(pas >= 0){ int nxt = dp[r][pas]; if(nxt != 0 && !isParent(nxt, b)) r = nxt; pas--; } if(!isParent(r, b)) r = dp[r][0]; return r; } int drum(int r, int lca){ int pas = nr_of_bits; int maxim = 0; while(pas >= 0){ int nxt = dp[r][pas]; if(nxt != 0 && !isParent(nxt, lca)){ maxim = max(maxim, cost[r][pas]); r = nxt; } pas--; } if(r != lca) maxim = max(maxim, cost[r][0]); return maxim; } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m >> q; for(int i = 1; i < NMAX; i++){ for(int j = i; j < NMAX; j+=i){ divs[i].push_back(j); } } for(int i = 1; i <= n + m; i++){ p[i] = i; cnt[i] = 1; } for(int i = m; i >= 1; i--){ for(auto x : divs[i]){ if(x > n) break; addEdge(x, n + i, (m - i + 1)); } } sort(edges.begin(), edges.end(), cmp); for(auto x : edges){ unite(x.from, x.to, x.cost); } DFS(1, 0); for(int j = 1; j <= nr_of_bits; j++){ for(int i = 1; i <= n + m; i++){ dp[i][j] = dp[dp[i][j - 1]][j - 1]; cost[i][j] = max(cost[i][j - 1], cost[dp[i][j - 1]][j - 1]); } } while(q--){ int x, y; cin >> x >> y; int lca = LCA(x, y); cout << max(drum(x, lca), drum(y, lca)) << "\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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...