题目
Prime XOR Coloring
每次测试时间限制:2秒
每个测试的内存限制:256 MB
给定一个有 n 个顶点的无向图,编号从 1 到 n。当且仅当 u 为素数时,顶点 u 和 v 之间存在边,其中 表示按位异或运算符。
使用最少数量的颜色为图的所有顶点着色,使得由边直接连接的两个顶点没有相同的颜色。
输入
每个测试包含多个测试用例。第一行包含测试用例的数量 t (1 < t < 500)。测试用例的描述如下。
唯一的一行包含一个整数 n (1 < n < 2e5) - 图中的顶点数。
保证所有测试用例的n之和不超过2e5。
输出
对于每个测试用例,输出两行。
第一行应包含单个整数 k (1 ≤ k ≤ n),即所需的最小颜色数。
第二行应包含 n 个整数 C1, C2,…, Cn (1 ≤ Ci <k) - 每个顶点的颜色。如果有多个解,输出任意一个。
范例输入
6
1
2
3
4
5
6
范例输出:
1
1
2
1 2
2
1 2 2
3
1 2 2 3
3
1 2 2 3 3
4
1 2 2 3 3 4
题目分析
重点就在于这个两个节点iXORj的值如果是质数那就存在一条边连接i和j
因此我们思考什么样的两个数XOR的结果是质数,或者,去思考质数的二进制表达有什么特点。
经过思考(打表)我们发现,所有的质数,在二进制位最后两位(2^0, 2^1)上至少有一位为1,也就是说最后两位不能都为0(不然就是4的倍数了)。但是并不是所有最后两位至少一位为1的数字他都是质数。
定义效果
f
(
i
,
j
)
=
(
i
⊕
j
)
∧
3
f(i,j)=(i\oplus j) \land 3
f(i,j)=(i⊕j)∧3
由上可以推出来,如果我保证所有
满足
f
(
i
,
j
)
!
=
0
的组合
(
i
,
j
)
中的
i
和
j
颜色不同,
满足f(i,j)!=0的组合(i,j)中的i和j颜色不同,
满足f(i,j)!=0的组合(i,j)中的i和j颜色不同,那么一定能够覆盖那些中间有路径的(i,j)组合。也就保证了这个图中由边直接连接的两个顶点没有相同的颜色。
然而我发现如果
i
∧
3
=
=
j
∧
3
,
那么
(
i
⊕
j
)
m
o
d
4
=
=
0
即
i
与
j
之间无直接路径
i\land 3 == j\land 3,那么(i\oplus j) mod 4 ==0即i与 j之间无直接路径
i∧3==j∧3,那么(i⊕j)mod4==0即i与j之间无直接路径
因此只需要给i节点赋予颜色种类为i^3+1那么就可以保证了同个颜色种类之间无直接路径,因此无论n多大,颜色种类最多为4种。
解答
完整代码
key part
码风模范jiangly
constexpr int arr[][7]={
{},
{1 },
{1, 2} ,
{1, 2, 2},
{1, 2, 2, 3},
{1, 2, 2, 3,3},
{1, 2, 2, 3,3, 4},
};
inline void solve() {
int n;cin>>n;
if(n<=6){
int ans=*max_element(arr[n],arr[n]+n);
cout<<ans<<endl;
for (int i=0;i<n;i++){
cout<<arr[n][i]<<" \n"[i==n-1];
}
}else{
cout<<4<<endl;
for(int i=1;i<=n;i++){
cout<<(i&3)+1<<" \n"[i==n];
}
}
}