B. Composite Coloring

题意

如果一个数字可以表示成两个数字的积,那么称这个数字为组合数。

给出一个由组合数构成的序列 \(a\) ,对序列中的数字染色(最多染 \(11\) 种颜色),要求染相同颜色的任意两个数字的 \(GCD\) 大于1。

构造出这样的染色方案,不要求用的颜色数量最少或者最多。

序列中的数字不超过1000。

分析

相同颜色的数字 \(GCD\) 大于1,那么可以按照质数倍数来染色,如果数字是某个质数的倍数,那么给它染某一种颜色。

序列中的数字不超过1000,那么质数最大只可能取到 \(\sqrt {1000} = 31\) ,而不超过31的质数正好有11个。

Code

#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <string>
#include <sstream>
#include <cstdlib>
#include <random>
#include <algorithm>

using namespace std;

#define closeSync ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
#define multiCase int T; cin >> T; while ( T -- )
#define mst(a, b) memset(a, b, sizeof(a))
#define lowbit(x) (x&(-x))
#define rep(i, x, y) for(int i = x; i <= y; i++)
#define repp(i, x, y) for (int i = x; i < y; i++)
#define per(i, x, y) for(int i = x; i >= y; i--)
#define perr(i, x, y) for (int i = x-1; i >= y; i--)
#define forr(x, s) for (auto x : s)
#define all(a) begin(a),end(a)
#define gti greater<int>()
#define qgti greater<int>
#define lc(x) (x<<1)
#define rc(x) (x<<1|1)
#define pb emplace_back
#define fi first
#define se second
#define debug(x) cout << #x << ": " << x << endl;
typedef vector<int> veci;
typedef vector<string> vecs;
typedef pair<int, int> PII;
typedef pair<string, int> PSI;
typedef pair<char, int> PCI;
typedef long long LL;
typedef unsigned long long ULL;

const int N = 2000010, M = 6000, mod = 1e6 + 7, INF = 0x3f3f3f3f;
const int strHash = 13333;
const double pi = acos(-1);
const double eps = 1e-7;

/************************************* Write here ******************************************/

int prima[11];
int st[11]; // 存储第i个质数使用的颜色

bool is_p (int v)
{
    for (int i = 2; i <= v / i; i ++ ) if (v % i == 0) return false;
    return true;
}

void init ()
{
    int nums = 0;
    rep(i, 2, 31) if (is_p(i)) prima[nums ++] = i;
}

void solve ()
{
    mst(st, -1);
    int n; cin >> n;
    veci color(n);

    int res = 0;
    repp(i, 0, n)
    {
        int x; cin >> x;
        repp(j, 0, 11)
            if (x % prima[j] == 0)
            {
                if (st[j] != -1) color[i] = st[j];
                else color[i] = st[j] = ++ res; 
                break;
            }
    }

    cout << res << endl;
    repp(i, 0, n) cout << color[i] << ' ';
    cout << endl;
}

/************************************* Write upon ******************************************/

/* Storms make trees take deeper roots.*/
signed main () 
{
    // closeSync
    
    init();
    multiCase
        solve();

    return 0;
}