通过与自身相反数做与运算获得该数的最右的1;
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int num,low;
};// num 记录该数,low记录最右的1;
int cmp(node a, node b){
return a.low > b.low;
}
node s[1000000+5];
int ans[1000000+5];
int main(){
int sum,lim;
cin >> sum >> lim;
for( int i = 1 ; i <= lim ; ++i ){
s[i].num = i;
s[i].low = i & (-i);
}
sort(s+1,s+1 + lim,cmp);//将lowbit从大到小排序
int cnt = 0;
//从大到小减直到sum为0,sum不为0则表示不能完成
for( int i = 1 ; i <= lim ; ++i ){
if(s[i].low <= sum){
sum -= s[i].low;
ans[++cnt] = s[i].num;//记录答案
}
if(sum == 0){
break;
}
}
if(sum){
cout << -1 << endl;
}
else{
cout << cnt << '\n';
for( int i = 1 ; i <= cnt ; ++i ){
cout << ans[i] << ' ';
}
cout << endl;
}
return 0;
}
P.S.
可以通过和自身-1做与运算去除最右的1