#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 = 17;
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;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
24 ms |
15564 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
29 ms |
15776 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
45 ms |
16220 KB |
Output is correct |
2 |
Correct |
46 ms |
15928 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
71 ms |
16348 KB |
Output is correct |
2 |
Correct |
51 ms |
16272 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
86 ms |
29676 KB |
Output is correct |
2 |
Correct |
72 ms |
26540 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
123 ms |
32900 KB |
Output is correct |
2 |
Correct |
92 ms |
29188 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
189 ms |
45200 KB |
Output is correct |
2 |
Correct |
135 ms |
40844 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
122 ms |
35668 KB |
Output is correct |
2 |
Correct |
229 ms |
52824 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
277 ms |
63108 KB |
Output is correct |
2 |
Correct |
266 ms |
60820 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Runtime error |
67 ms |
65536 KB |
Execution killed with signal 9 |
2 |
Halted |
0 ms |
0 KB |
- |