各点的&和,只可能是1或0。
如果是偶数节点,&1,得0。
如果是奇数节点,确定从该数二进制最高位起它的第一个0的位置,再找对应位置是1、其余位是0的数。如果这个数超过n,就&1,否则就&这个数。
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
scanf("%d",&t);
while(t--){
vector<int> vec;
int n;
scanf("%d",&n);
int sum=0;
for(int i=2;i<=n;++i){
if(!(i&1)) vec.push_back(1);
else{
int tmp=i,cnt=0;
bool flag=0;//全1特判
while(tmp){
int b=tmp&1;
++cnt;
tmp>>=1;
if(!b){
flag=1;//有0
break;
}
}
if(!flag) ++cnt; //全1 0的位置为位数+1
int ans=1<<(cnt-1);
if(ans>n) {
sum+=1;
vec.push_back(1);
}else{
sum=sum+(i&ans);
vec.push_back(ans);
}
}
}
printf("%d\n",sum);
for(int i=0;i<vec.size();++i){
if(i)printf(" ");
printf("%d",vec[i]);
}
puts("") ;
}
}