Description
在此题中,对于一个数 x x x,若 popcount ( x ) ≥ 3 \texttt{popcount}(x)\geq3 popcount(x)≥3(即 x x x 在二进制下 1 \texttt{1} 1 的个数大于等于三时),那它是非法的,否则其为合法的。
给定
T
T
T 个数,如果当前的数
x
x
x 是非法的,则输出 No,Commander
,否则输出第一个大于
x
x
x 的合法的数。
Solution
对于一个数 x x x,我们可以快速得出 popcount ( x ) \texttt{popcount}(x) popcount(x),若为非法,直接输出答案,否则还剩三种情况:
- popcount ( x ) = 0 \texttt{popcount}(x)=0 popcount(x)=0,说明 x = 0 x=0 x=0,输出 1 \texttt{1} 1 即可。
- popcount ( x ) = 1 \texttt{popcount}(x)=1 popcount(x)=1,输出 x + 1 x+1 x+1 即可,因为 popcount ( x + 1 ) = 2 \texttt{popcount}(x+1)=2 popcount(x+1)=2( popcount ( 1 + 1 ) = 1 \texttt{popcount}(1+1)=1 popcount(1+1)=1 为特例)
- popcount ( x ) = 2 \texttt{popcount}(x)=2 popcount(x)=2,设答案为 y y y,若 popcount ( y ) = 1 \texttt{popcount}(y)=1 popcount(y)=1 ,则 y = 2 ⌈ log 2 x ⌉ + 1 y=2^{\left\lceil\log_2{x}\right\rceil+1} y=2⌈log2x⌉+1,比如 x = 10100 x=\texttt{10100} x=10100 时 y = 100000 y=100000 y=100000,而 popcount ( y ) = 2 \texttt{popcount}(y)=2 popcount(y)=2 时,则需要找到其从低到高第一个 1 1 1 的位置 k k k, y = x + 2 k − 1 y=x+2^{k-1} y=x+2k−1,因为在把第 k k k 位的 1 \texttt{1} 1 消掉时,能同时加 1 \texttt{1} 1 到 k + 1 k+1 k+1 位上,如 x = 10100 x=10100 x=10100 时 y = 11000 y=11000 y=11000,要比第一种更小,综上,输出 x + 2 k − 1 x+2^{k-1} x+2k−1 即可。
Code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int t;
int check(ll num){ // 得出popcount(x)
int cnt=0;
while(num){
if(num&1){
cnt++;
}
num>>=1;
}
return cnt;
}
ll next(ll x){ //记得开 long long
if(check(x)==1||check(x)==0) return x+1;
int cnt=0;
ll y=x;
while(x){
if(x&1) break; //找到 k
x/=2;
cnt++;
}
ll xx=pow(2,cnt); // 加上 2^{k-1}
return (ll)(y+xx);
}
int main(){
cin>>t;
while(t--){
ll x;
cin>>x;
if(check(x)>=3) cout<<"No,Commander"<<endl;
else cout<<next(x)<<endl;
}
return 0;
}