QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#603612#9309. GraphRozannaHuangWA 1ms3732kbC++142.4kb2024-10-01 17:48:142024-10-01 17:48:14

Judging History

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

  • [2024-10-01 17:48:14]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3732kb
  • [2024-10-01 17:48:14]
  • 提交

answer

#include <iostream>
#include <vector>
#include <unordered_set>
#include <algorithm>

using namespace std;

const int MOD = 998244353;

// 并查集实现
vector<int> parent, size;

// 查找根节点
int find(int x) {
    if (parent[x] != x) {
        parent[x] = find(parent[x]); // 路径压缩
    }
    return parent[x];
}

// 合并操作
void unite(int x, int y) {
    int rootX = find(x);
    int rootY = find(y);
    if (rootX != rootY) {
        if (size[rootX] < size[rootY]) swap(rootX, rootY);
        parent[rootY] = rootX;
        size[rootX] += size[rootY];
    }
}

// 计算所有连通块的数量
vector<int> countConnectedComponents(int n) {
    unordered_set<int> roots;
    for (int i = 1; i <= n; ++i) {
        roots.insert(find(i));
    }
    
    // 返回所有连通块的大小
    vector<int> componentSizes;
    for (int root : roots) {
        componentSizes.push_back(size[root]);
    }
    
    return componentSizes;
}

// 计算生成树的数量
long long countTrees(const vector<int>& sizes) {
    int k = sizes.size(); // 连通块数量
    if (k == 0) return 0; // 没有连通块
    if (k == 1) return 1; // 只有一个连通块

    // 计算生成树的数量
    long long totalWays = 1;

    // 计算每对连通块之间的边的数量
    for (int i = 0; i < k; ++i) {
        for (int j = i + 1; j < k; ++j) {
            // 每对连通块之间有两种连接方式
            totalWays = (totalWays * 2) % MOD;
        }
    }

    // 乘上每个连通块内部的生成树数量
    for (int size : sizes) {
        // 每个连通块有 (size) 选择的边
        totalWays = (totalWays * size) % MOD;
    }

    return totalWays;
}

int main() {
    int n;
    cin >> n;

    // 初始化并查集
    parent.resize(n + 1);
    size.assign(n + 1, 1); // 每个集合的初始大小为1
    for (int i = 1; i <= n; ++i) {
        parent[i] = i; // 初始化每个元素的父节点
    }

    // 按素数的倍数合并
    for (int i = 2; i <= n; ++i) {
        for (int j = 2 * i; j <= n; j += i) {
            unite(i, j);
        }
    }

    // 统计连通块的数量和大小
    vector<int> componentSizes = countConnectedComponents(n);

    // 计算最小生成树的数量
    long long result = countTrees(componentSizes);
    cout << result << '\n';

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 1ms
memory: 3732kb

input:

4

output:

16

result:

wrong answer expected '8', found '16'