題目鏈接:https://codeforces.com/contest/1152/problem/B
題意:給你一個數x,你可以對其進行兩種操作:
操作A: 選擇一個非負數:n,然後將 x與(2^n - 1)進行異或
操作B: 將x自增1
其中第一種操作必選爲A,然後緊跟着B操作,即操作必須爲ABAB....A或ABAB..AB。要求最後的x可以變爲
即x = (2^m - 1)
思路:用(2^m - 1)【全1的數】進行異或操作的結果爲:取反。對於每次被B操作完的x,從右向左找出第一個0,然後算出從這位起一直到最後的位數cnt,用cnt個1的數進行異或一下,即把首位的0變爲了1。這樣不斷下去,一定爲將x變爲全1。
技巧操作:位運算:
取出整數n在二進制表示下的第k位 ---》 (n >> k) & 1
取出整數n在二進制表示下的第0~(k-1)位 ---》 n & ((1 << k) -1 )
代碼:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#define Fin freopen("in.txt","r",stdin)
#define Fout freopen("out.txt","w",stdout)
#define Case(T) int T;for(scanf("%d",&T);T--;)
#define fo(i,a,b) for(int i = a; i < b; ++i)
#define fd(i,a,b) for(int i = a; i >= b; --i)
#define me(a,b) memset(a,b,sizeof(a))
#define fi(a,n,val) fill(a,a+n,val)
#define Scand(n) scanf("%d",&n)
#define Scand2(a,b) scanf("%d%d",&a,&b)
#define Scand3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define Scand4(a,b,c,d) scanf("%d%d%d%d",&a,&b,&c,&d)
#define Scans(s) scanf("%s",s)
#define random(a,b) a+rand()%(b-a+1)
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b ? gcd(b,a%b): a; }
const int maxn = 1e4 + 50;
const int INFint = 0xffffff;
const ll INFll = (ll)1e18;
#ifndef ONLINE_JUDGE
#endif // ONLINE_JUDGE
inline int readint(){
int sgn = 1; int sum = 0;
char ch = getchar();
while (ch < '0' || ch > '9') {
if(ch == '-') sgn = -sgn;
ch = getchar();
}
while ('0' <= ch && ch <= '9') {
sum = sum*10+(ch-'0');
ch = getchar();
}
return sgn*sum;
}
inline ll readll(){
ll sgn = 1; ll sum = 0;
char ch = getchar();
while (ch < '0' || ch > '9') {
if(ch == '-') sgn = -sgn;
ch = getchar();
}
while ('0' <= ch && ch <= '9') {
sum = sum*10+(ch-'0');
ch = getchar();
}
return sgn*sum;
}
int n;
int calc(int n){
int tmp = n;
int num = 0;
while(n >> 1){
num++;
n >>= 1;
}
num++;
return num;
}
int fun(int n){
int num = calc(n);
// printf("num:%d\n", num);
for(int i = num; i >= 1; --i){
int tmp = (n >> (i-1)) & 1;
// printf("i:%d tmp:%d\n", i, tmp);
if(tmp == 0){
return i;
}
}
return 0;
}
int judge(int n){
int num = calc(n);
if(n == int(pow(2, num) - 1))
return 1;
return 0;
}
int main()
{
#ifndef ONLINE_JUDGE
//Fin;
#endif // ONLINE_JUDGE
// int t = 10;
// while(t--){
// int n = readint();
// cout << fun(n) << endl;
// }
n = readint();
if(fun(n) == 0){
cout << 0;
return 0;
}
int cnt = 0;
vector<int> v;
while(!judge(n)){
// printf("before n:%d\n", n);
int num = fun(n);
int tmp = pow(2, num) - 1;
n ^= tmp;
cnt++;
// printf("num:%d tmp:%d n:%d cnt:%d\n", num, tmp, n, cnt);
v.push_back(num);
if(judge(n)){
cout << cnt << endl;
int Size = v.size();
for(int i = 0; i < Size; ++i){
if(i == 0)
cout << v[i];
else
cout << ' ' << v[i];
}
break;
}
n++;
cnt++;
if(judge(n)){
cout << cnt << endl;
int Size = v.size();
for(int i = 0; i < Size; ++i){
if(i == 0)
cout << v[i];
else
cout << ' ' << v[i];
}
break;
}
}
return 0;
}