QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#255791 | #7749. A Simple MST Problem | ucup-team055# | TL | 219ms | 71320kb | C++20 | 2.3kb | 2023-11-18 17:07:09 | 2023-11-18 17:07:10 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, a, b) for (ll i = a; i < b; i++)
#define all(a) begin(a), end(a)
template <class T> bool chmin(T &a, T b) {
if (a <= b)
return 0;
a = b;
return 1;
}
template <class T> bool chmax(T &a, T b) {
if (a >= b)
return 0;
a = b;
return 1;
}
struct UnionFind {
vector<ll> uf;
UnionFind(ll n) : uf(n, -1) {}
ll root(ll x) {
if (uf[x] < 0)
return x;
return uf[x] = root(uf[x]);
}
bool unite(ll x, ll y) {
x = root(x);
y = root(y);
if (x == y)
return 0;
if (uf[x] > uf[y])
swap(x, y);
uf[x] += uf[y];
uf[y] = x;
return 1;
}
};
void solve() {
int l, r;
cin >> l >> r;
struct edge {
int to, c;
};
const int n = r + 1;
vector<vector<edge>> g(n + n);
const auto add_edge = [&](int u, int v, int c) {
g[u].push_back({v, c});
g[v].push_back({u, c});
};
vector<int> w(n);
rep(p, 2, n) {
if (w[p] != 0)
continue;
for (int i = p; i < n; i += p) {
w[i]++;
}
for (int i = 1; i * p < n; i++)
add_edge(i, i * p, i % p ? 1 : 0);
}
rep(i, l, r + 1) add_edge(i, n + i, w[i]);
struct outer_edge {
int u, v, c;
};
vector<outer_edge> edges;
struct node {
int v, f;
int c;
bool operator<(const node &r) const { return c > r.c; }
};
priority_queue<node> pq;
const int inf = 1e8;
vector<int> dist(n + n, inf);
vector<int> from(n + n, -1);
rep(i, l, r + 1) pq.push({n + int(i), int(i), 0});
while (!pq.empty()) {
const auto [v, f, d] = pq.top();
pq.pop();
if (dist[v] != inf && from[v] != f) {
edges.push_back({from[v], f, dist[v] + d});
continue;
}
dist[v] = d;
from[v] = f;
for (const auto &[to, c] : g[v]) {
if (dist[to] == inf)
pq.push({to, f, d + c});
}
}
int ans = 0;
UnionFind uf(n);
sort(all(edges), [](const auto &e, const auto &f) { return e.c < f.c; });
int cnt = 0;
for (const auto &[u, v, c] : edges) {
if (uf.unite(u, v))
cnt++, ans += c;
}
assert(cnt == r - l);
cout << ans / 2 << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--)
solve();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3828kb
input:
5 1 1 4 5 1 4 1 9 19 810
output:
0 2 3 9 1812
result:
ok 5 lines
Test #2:
score: 0
Accepted
time: 206ms
memory: 71320kb
input:
2 27 30 183704 252609
output:
8 223092
result:
ok 2 lines
Test #3:
score: 0
Accepted
time: 219ms
memory: 71200kb
input:
1 183704 252609
output:
223092
result:
ok single line: '223092'
Test #4:
score: -100
Time Limit Exceeded
input:
2 639898 942309 30927 34660