题解:CF2072C Creating Keys for StORages Has Become My Main Skill
本文介绍了解决CF2072C题目的思路和代码实现。题目要求构造长度为n的数组,使其按位或结果为x,同时使得数组的MEX值(最小缺失非负整数)最大化。关键在于贪心策略:尽可能包含0到n-1的连续自然数,当这些数的或运算结果无法达到x时就补上x。代码通过遍历0到n-1的数进行或运算,当发现无法满足条件时直接填充x,从而保证结果满足题目要求。该方法高效简洁,适用于大规模输入数据。
CF2072C Creating Keys for StORages Has Become My Main Skill
题目描述
Akito 仍然无处可住,而小房间的价格却居高不下。为此,Akito 决定在银行找一份为存储设备创建密钥的工作。
在这个魔法世界中,一切都与众不同。例如,代码为 ( n , x ) (n, x) (n,x) 的存储设备的密钥是一个满足以下条件的长度为 n n n 的数组 a a a:
- a 1 ∣ a 2 ∣ a 3 ∣ … ∣ a n = x a_1 \mid a_2 \mid a_3 \mid \ldots \mid a_n = x a1∣a2∣a3∣…∣an=x,其中 a ∣ b a \mid b a∣b 表示数 a a a 和 b b b 的按位或运算。
- MEX ( { a 1 , a 2 , a 3 , … , a n } ) \text{MEX}(\{ a_1, a_2, a_3, \ldots, a_n \}) MEX({a1,a2,a3,…,an}) ∗ ^{\text{∗}} ∗ 在所有满足条件的数组中达到最大值。
Akito 勤奋地工作了几个小时,但突然头痛发作。请代替他工作一小时:对于给定的 n n n 和 x x x,创建任意一个满足代码为 ( n , x ) (n, x) (n,x) 的存储设备的密钥。
∗ ^{\text{∗}} ∗ MEX ( S ) \text{MEX}(S) MEX(S) 是满足以下条件的最小非负整数 z z z: z z z 不在集合 S S S 中,且所有满足 0 ≤ y < z 0 \le y < z 0≤y<z 的 y y y 都在集合 S S S 中。
输入格式
第一行包含一个数 t t t( 1 ≤ t ≤ 10 4 1 \le t \le 10^4 1≤t≤104)——测试用例的数量。
每个测试用例的唯一一行包含两个数 n n n 和 x x x( 1 ≤ n ≤ 2 ⋅ 10 5 1 \le n \le 2 \cdot 10^5 1≤n≤2⋅105, 0 ≤ x < 2 30 0 \le x < 2^{30} 0≤x<230)——数组的长度和按位或运算的目标值。
保证所有测试用例的 n n n 之和不超过 2 ⋅ 10 5 2 \cdot 10^5 2⋅105。
输出格式
对于每个测试用例,输出 n n n 个整数 a i a_i ai( 0 ≤ a i < 2 30 0 \le a_i < 2^{30} 0≤ai<230)——满足所有条件的密钥数组元素。
如果存在多个符合条件的数组,输出其中任意一个即可。
形式化题面
给你两个整数 n n n 和 x x x,你需要构造一个长度为 n n n 的数列,使整个数列或起来的结果为 x x x,且包含尽量多的从零开始的连续的数。
思路
本题并没有用什么高超的算法。
我们知道,一个数或上另一个数,每一个二进制位一定不会减少。所以,从零考虑,依次或上连续的自然数,当结果有一位大于 n n n 时,就没有办法或上任何个数的数结果为 n n n 了。
如果将 0 到 n − 1 n-1 n−1 的数或起来,仍然到不了 x x x,则 MEX 值一定到不了 n n n ,而如果我们的方案 MEX 值为 n − 1 n-1 n−1,则是最优解。
于是可以贪心……
code
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
int n,x,cnt=0;
cin>>n>>x;
for(int i=0;i<n;i++){
cnt|=i;
if((cnt|x)>x){//当或上这个数cnt有任意一位大于x
for(;i<n;i++){//不要这个数了,最后输出x凑数
cout<<x<<" ";
}
break;
}
if(i==n-1){
if(cnt<x){//把0到n-1全或上也不够x
cout<<x;//直接或上x不就够了吗
break;
}
}
cout<<i<<" ";
}
cout<<'\n';
}
return 0;
}
更多推荐
所有评论(0)