位运算或和MEX
Creating Keys for StORages Has Become My Main Skill
例如,代码为(n,x) 的存储空间的密钥是一个长度为 n 的数组 a ,
-
a1 | a2 | a3 | … | an=x 其中 a | b是数字 a 和 b 的按位 " OR"
-
在所有这样的数组中, 要使得MEX({a1,a2,a3,…,an})是最大值。
∗ MEX(S) 是最小的非负整数 z ,使得 z 不包含在集合 S 中,且所有 0≤y<z 都包含在 S 中。
输入
第一行包含 t ( 1≤t≤1e4 ) - 测试用例数。
在每个测试用例的唯一一行中,给出了两个数字 n 和 x( 1≤n≤2⋅105,0≤x<230)。
保证所有测试用例中 n 的总和不超过 2e5。
输出
针对每个测试用例,输出 n 个整数 ai( 0≤ai<2^30 )。
如果有多个合适的数组,则输出其中任意一个。
分析
本来是想求末位有几个连续的1...但是这并不是个好思路,处理起来也异常复杂,需要非常细致的分类讨论
1200的题真的有这么大的码量吗? 显然我的思路并不是最优解, 于是还是点开了洛谷题解, 来自作者tzzl3035
从 0 开始向后枚举,若或上这个数不会使最终的 x 改变,则加上这个数,否则不枚举了。若枚举完后发现按位或的和不够 x,把最后一位改为 x 即可。
if((i|x)==x) 注意这里的位运算必须加上括号,建议所有的位运算都用括号包起来
ac代码
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define all(x) (x).begin(),(x).end()
#define endl '\n'
#define int long long
const int N=3e5+5;
void solve(){
int n,x;cin>>n>>x;
vector<int> v;
int sum=0;
for(int i=0;i<=n-1;i++){
if((i|x)==x){ // 不得不说这一行挺巧妙的, 省去了处理一个二进制数末位1的个数的复杂讨论
v.push_back(i);
sum|=i;
}else{
break;
}
}
if(v.size()<n){
while(v.size()<n)v.push_back(x);
for(auto i:v)cout<<i<<' ';
cout<<endl;
}else{
if(sum!=x){
v.pop_back();
v.push_back(x);
}
for(auto i:v)cout<<i<<' ';
cout<<endl;
}
}
signed main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int _;cin>>_;while(_--)
solve();
return 0;
}
题目来自Codeforces Round 1006 (Div. 3) C. Creating Keys for StORages Has Become My Main Skill

浙公网安备 33010602011771号