QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#256449#7749. A Simple MST Problemucup-team228#TL 992ms195516kbC++204.9kb2023-11-18 19:26:272023-11-18 19:26:27

Judging History

你现在查看的是最新测评结果

  • [2023-11-18 19:26:27]
  • 评测
  • 测评结果:TL
  • 用时:992ms
  • 内存:195516kb
  • [2023-11-18 19:26:27]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

struct DSU {
    static const int N = 1e6 + 10;
    int Parent[N], Rank[N], Size[N], cnt;
    void init(int n) {
        for (int i = 1; i <= n; i++) {
            Parent[i] = i, Rank[i] = 0, Size[i] = 1;
        }
        cnt = n;
    }
    int find(int v) {
        if (Parent[v] == v) return v;
        else return Parent[v] = find(Parent[v]);
    }
    void unite(int u, int v) {
        u = find(u), v = find(v);
        if (u == v) return;
        if (Rank[u] < Rank[v]) swap(u, v);
        if (Rank[v] == Rank[u]) Rank[u]++;
        Parent[v] = u, cnt--;
        Size[u] += Size[v];
    }
};

DSU dsu;

const int MAX_DIV = 7;
const int C = 1e6 + 10;
bool prime[C];
int prime_div[C];
vector<int> pf[C];
vector<vector<int>> vec[C];

void find_primes() {
    for (int i = 0; i <= C - 1; i++) {
        prime[i] = true;
        prime_div[i] = i;
    }
    prime[0] = prime[1] = false;
    for (int i = 2; i <= C - 1; i++) {
        if (prime[i]) {
            if (i * 1ll * i <= C - 1) {
                for (int j = i * i; j <= C - 1; j += i) {
                    prime[j] = false;
                    prime_div[j] = i;
                }
            }
        }
    }
    for (int i = 2; i <= C - 1; i++) {
        if (prime[i]) {
            pf[i] = {i};
        } else {
            pf[i] = pf[i / prime_div[i]];
            bool ok = true;
            for (int j = 0; j < pf[i].size(); j++) {
                if (pf[i][j] == prime_div[i]) {
                    ok = false;
                }
            }
            if (ok) {
                pf[i].push_back(prime_div[i]);
                for (int j = int(pf[i].size()) - 1; j >= 1; j--) {
                    if (pf[i][j - 1] > pf[i][j]) {
                        swap(pf[i][j - 1], pf[i][j]);
                    }
                }
            }
        }
    }
    int tot = 0;
    for (int i = 1; i <= C - 1; i++) {
        int red = 1;
        for (int p : pf[i]) {
            red *= p;
        }
        int k = pf[red].size();
        tot += (1 << k);
        for (int mask = 0; mask < (1 << k); mask++) {
            int g = 1;
            for (int i = 0; i < k; i++) {
                if (mask & (1 << i)) {
                    g *= pf[red][i];
                }
            }
            int l = k - __builtin_popcount(mask);
            while (vec[g].size() < l + 1) {
                vec[g].push_back({});
            }
            vec[g][l].push_back(i);
        }
    }
}

int solve(int l, int r) {
    int ans = 0;
    dsu.init(r);

    for (int cost = 1; cost <= 2 * MAX_DIV - 1; cost++) {
        for (int g = 1; g <= r; g++) {
            if (pf[g].size() > cost) {
                continue;
            }
            if (!((cost - pf[g].size()) & 1)) {
                int x_cnt = (cost - pf[g].size()) / 2;
                if (x_cnt < vec[g].size()) {
                    for (int i = 0; i + 1 < vec[g][x_cnt].size() && vec[g][x_cnt][i + 1] <= r; i++) {
                        if (l <= vec[g][x_cnt][i] && dsu.find(vec[g][x_cnt][i]) != dsu.find(vec[g][x_cnt][i + 1])) {
                            dsu.unite(vec[g][x_cnt][i], vec[g][x_cnt][i + 1]);
                            ans += cost;
                        }
                    }
                }
            }
            for (int x_cnt = 0; x_cnt + x_cnt < cost - pf[g].size(); x_cnt++) {
                if (x_cnt >= vec[g].size()) {
                    continue;
                }
                int y_cnt = cost - pf[g].size() - x_cnt;
                if (y_cnt >= vec[g].size()) {
                    continue;
                }
                int mem_x = 0;
                for (int x : vec[g][x_cnt]) {
                    if (x > r) {
                        break;
                    } else if (l <= x) {
                        mem_x = x;
                        break;
                    }
                }
                if (!mem_x) {
                    continue;
                }
                for (int y : vec[g][y_cnt]) {
                    if (y > r) {
                        break;
                    } else if (l <= y) {
                        if (dsu.find(mem_x) != dsu.find(y)) {
                            dsu.unite(mem_x, y);
                            ans += cost;
                        }
                    }
                }
            }
        }
    }
    return ans;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
#endif

    find_primes();

    int t;
    cin >> t;
    while (t--) {
        int l, r;
        cin >> l >> r;
        cout << solve(l, r) << "\n";
    }

#ifdef LOCAL
    cout << "\nTime elapsed: " << double(clock()) / CLOCKS_PER_SEC << " s.\n";
#endif
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 626ms
memory: 188580kb

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: 713ms
memory: 192676kb

input:

2
27 30
183704 252609

output:

8
223092

result:

ok 2 lines

Test #3:

score: 0
Accepted
time: 724ms
memory: 189476kb

input:

1
183704 252609

output:

223092

result:

ok single line: '223092'

Test #4:

score: 0
Accepted
time: 926ms
memory: 195516kb

input:

2
639898 942309
30927 34660

output:

983228
11512

result:

ok 2 lines

Test #5:

score: 0
Accepted
time: 807ms
memory: 194880kb

input:

3
21731 33468
46192 370315
1712 3753

output:

34608
948775
5299

result:

ok 3 lines

Test #6:

score: 0
Accepted
time: 736ms
memory: 193956kb

input:

4
15237 67700
10918 86104
98287 116980
17432 23592

output:

148811
210927
60893
18687

result:

ok 4 lines

Test #7:

score: 0
Accepted
time: 992ms
memory: 194840kb

input:

5
5594 70302
19202 69588
5634 7877
59821 469300
97439 261121

output:

179735
145706
6565
1203684
488669

result:

ok 5 lines

Test #8:

score: -100
Time Limit Exceeded

input:

6
43477 229639
188276 269887
72424 150178
9009 36918
137421 180271
14666 124530

output:

541705
255651
232054
77284
135277
313203

result: