#include <bits/stdc++.h>
using namespace std;
std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
typedef unsigned long long ull;
typedef std::pair<int, int> ii;
/////////////////////////////////////////////////////// BEGIN OF UNION-FIND WITH PARTIAL PERSISTENCY ///////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
//////////////// Note: this class supports both 0-indexed and 1-indexed elements ////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
class UnionFindPartial {
private:
int m_current_time;
std::vector<int> m_parent; // [0 .. size]
std::vector<int> m_time; // [0 .. size]
std::vector<int> m_size; // [0 .. size]
public:
UnionFindPartial(const int size) {
m_current_time = 0;
m_parent.reserve(size+1);
m_time.reserve(size+1);
m_size.reserve(size+1);
for (int i = 0; i <= size; ++i) {
m_parent.push_back(i);
m_time.push_back(0);
m_size.push_back(1);
}
}
inline int time() const {
return m_current_time;
}
inline int find(int x, const int last_time) const {
while (m_time[x] <= last_time && x != m_parent[x])
x = m_parent[x];
return x;
}
inline int find(const int x) const {
return find(x, time());
}
void merge(const int a, const int b) {
const int gpa = find(a);
const int gpb = find(b);
m_current_time += 1;
if (gpa != gpb) {
if (m_size[gpa] < m_size[gpb]) {
m_parent[gpa] = gpb;
m_size[gpb] += m_size[gpa];
m_time[gpb] = m_current_time;
} else {
m_parent[gpb] = gpa;
m_size[gpa] += m_size[gpb];
m_time[gpb] = m_current_time;
}
}
}
bool same(const int a, const int b) {
return find(a) == find(b);
}
bool same(const int a, const int b, const int last_time) {
return find(a, last_time) == find(b, last_time);
}
inline int find_time(int a, int b) {
int ans = 0;
while (a != b) {
//cout<<"a"<<endl;
if (m_parent[a] == a && m_parent[b] == b) break;
//printf("%d %d %d %d\n", a, b, m_parent[a], m_parent[b]);
if ((m_time[a] <= m_time[b] && m_parent[a] != a) || m_parent[b] == b) {
ans = max(ans, m_time[a]);
a = m_parent[a];
} else {
ans = max(ans, m_time[b]);
b = m_parent[b];
}
}
return ans;
}
int size(const int a) {
const int gpa = find(a);
return m_size[gpa];
}
};
/////////////////////////////////////////////////////// END OF UNION-FIND WITH PARTIAL PERSISTENCY ///////////////////////////////////////////////////////
int32_t main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n, m, q;
cin>>n>>m>>q;
UnionFindPartial uf(2*n);
map<int, int> ans;
ans[uf.time()] = 0;
for (int day = m; day >= 1; --day) {
for (int i = 2; i*day <= n; ++i) {
uf.merge(day, i*day);
ans[uf.time()] = m-day+1;
}
}
while (q--) {
int a, b;
cin>>a>>b;
int time = uf.find_time(a, b);
cout<<ans[time]<<'\n';
}
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
5 ms |
488 KB |
Output isn't correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
8 ms |
632 KB |
Output isn't correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
23 ms |
1400 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
35 ms |
1828 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
85 ms |
11128 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
139 ms |
15992 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
207 ms |
23732 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
180 ms |
18772 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
355 ms |
41848 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
652 ms |
54576 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |