1 条题解

  • 0
    @ 2026-5-4 17:24:55

    题意简述

    有一张 nn 个点的无向图,顶点 u,vu,v 之间有边当且仅当 uvu \oplus v 是质数。求图的最小染色数及方案。

    性质分析

    两个数的 XOR 为奇数当且仅当它们奇偶性不同,为偶数当且仅当奇偶性相同。
    22 以外的质数都是奇数,因此仅考虑奇质数时,图是一个二分图(奇偶分层)。
    但偶质数 22 会产生边,例如 13=21 \oplus 3 = 224=22 \oplus 4 = 2 等,这些边的两端奇偶性相同且相差 22

    最小颜色数

    • n=1n = 1 时,显然 11 种颜色。
    • n=2n = 2 时,1122 之间有边(12=31\oplus2=3),需要 22 种颜色。
    • n=3n = 3 时,2233 之间无边,可以用 22 种颜色(如 1,2,21,2,2)。
    • n=4n = 4 时,需要 33 种颜色。
    • n=5n = 5 时,需要 33 种颜色。
    • n6n \ge 6 时,最少需要 44 种颜色。

    构造方案(n6n \ge 6

    使用 44 种颜色,按顶点编号模 44 的余数染色:ci=(i1)mod4+1c_i = (i-1) \bmod 4 + 1

    证明
    若两个顶点同色,则它们的编号模 44 同余,因此它们的 XOR 是 44 的倍数。
    唯一的偶质数是 22,但不能被 44 整除;奇质数不可能被 44 整除。
    因此同色顶点之间的 XOR 不可能是质数,即不存在同色边。该染色合法。

    对于 n<6n < 6,可以直接使用预构造的最优方案。

    复杂度

    对于每组数据,输出 O(n)O(n) 个整数。总复杂度 O(n)2×105O(\sum n) \le 2 \times 10^5,非常快。

    参考代码

    #include <bits/stdc++.h>
    using namespace std;
    
    void solve() {
        int n;
        cin >> n;
        if (n == 1) {
            cout << "1\n1\n";
        } else if (n == 2) {
            cout << "2\n1 2\n";
        } else if (n == 3) {
            cout << "2\n1 2 2\n";
        } else if (n == 4) {
            cout << "3\n1 2 2 3\n";
        } else if (n == 5) {
            cout << "3\n1 2 2 3 3\n";
        } else {
            // n >= 6,总是 4 色,按 mod 4 染色
            cout << "4\n";
            for (int i = 1; i <= n; ++i) {
                int c = (i - 1) % 4 + 1;
                cout << c << " \n"[i == n];
            }
        }
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) solve();
        return 0;
    }
    
    • 1

    信息

    ID
    6820
    时间
    2000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者