CF1688A Cirnos Perfect Bitmasks Classroom

题意

给出一个正整数 xx,求出一个最小的正整数 yy,使得 x and y>0x\text{ and }y>0x xor y>0x\text{ xor }y>0

分析

根据按位与和按位异或的性质,题目的两个条件可以理解为 x,yx,y 在二进制表示下至少有一位相同 (and)(\text{and}),至少有一位不同 (xor)(\text{xor})

显然最小的正整数为 11,我们从 11 的角度出发,可以发现以下两个性质:

  • x=1x=1,根据样例可以得到 yy 最小为 11(2)11_{(2)}
  • xx 为大于 11 的奇数,yy 最小为 1(2)1_{(2)},因为此时 yy 末尾必与 xx 相同且其他位有不同的。

然后考虑 xx 为偶数时的解法。

为了让 yy 尽可能小,我们让它与 xx 重合的那位尽可能小,易知 xx 二进制的最低位为 lowbit(x)=x&-x\text{lowbit}(x)=\texttt{x\&-x},那么:

  • xx 在二进制下每位上 11 的个数大于 11,说明 y=lowbit(x)y=\text{lowbit}(x)xx 至少有一位不同,且此时 yy 最小。
  • xx 在二进制下每位上 11 的个数等于 11,说明 y=lowbit(x)y=\text{lowbit}(x)xx 完全相同,为了让他们不同,末位改成 11 就可以了。

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
long long read(){
	long long x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
void write(long long x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}
int t;
int main(){
	t=read();
	while(t--){
		ll n=read();
		if(n==1)
			puts("3");
		else if(n&1)
			puts("1");
		else{
			if((n&-n)==n)
				write(n+1);
			else
				write(n&-n);
			puts("");
		}
	}
	return 0;
}
posted @ 2022-06-05 00:26  luckydrawbox  阅读(11)  评论(0)    收藏  举报  来源