#include <iostream> #include <vector> #include <algorithm> #include <set> #include <math.h> #include <stdio.h> #include <deque> #include <unordered_map> #include <cassert> #include <numeric> #include <queue> #include <list> #include <string> #include <stack> #define LL long long #define MOD 1000000007 using namespace std; vector<vector<int> > SAME_BITCOUNT_NUMBERS; int bruteFindFirstGreaterThan(int x, int bits, int maxmax) { int y = x+1; while (__builtin_popcount(y) != bits) { y++; if (y>=maxmax || y > 130000) return y; } return y; } int findFirstGreaterThan(int x, int bits, int maxmax) { vector<int> &v = SAME_BITCOUNT_NUMBERS[bits]; auto it = lower_bound(v.begin(), v.end(), x); while (it != v.end()) { if (*it > x) return *it; ++it; } //assert(false); return 130000; } void initialVector(const int requiredBits, vector<int> &v) { const int INF = 1000010; vector<int> dp(requiredBits+1, INF); int i = 0; dp[0] = 0; dp[1] = 1; int bits = 1; for (int i=2;;i++) { bits += __builtin_popcount(i); //printf("bits=%d\n", bits); if (bits > requiredBits) break; dp[bits] = i; } //printf("before: "); for (int i=1; i <= requiredBits; i++) printf("dp[%d]=%d\n", i, dp[i]); for (int i=2; i <= requiredBits; i++) { if (dp[i] != INF) continue; for (int j=1; j < 18 && j <= i-1; j++) { int candidate = findFirstGreaterThan(dp[i-j], j, dp[i]); //printf("i:%d, candidate:%d\n", i, candidate); dp[i] = min(dp[i], candidate); } } //printf("after:\n"); for (int i=1; i <= requiredBits; i++) printf("dp[%d]=%d\n", i, dp[i]); v.clear(); bits = requiredBits; while (bits) { int prev = dp[bits]; v.push_back(prev); bits -= __builtin_popcount(prev); } return; } bool verify(const vector<int> &v, const int requiredBits) { int res = __builtin_popcount(v[0]); for (int i=1; i < v.size(); i++) { assert (v[i-1] > v[i]); res += __builtin_popcount(v[i]); } assert (res == requiredBits); //printf("all good\n"); return res == requiredBits; } #define uint_t unsigned int uint_t next_same_bits(uint_t x) { uint_t rightOne; uint_t nextHigherOneBit; uint_t rightOnesPattern; uint_t next = 0; if(x) { // right most set bit rightOne = x & -(signed)x; // reset the pattern and set next higher bit // left part of x will be here nextHigherOneBit = x + rightOne; // nextHigherOneBit is now part [D] of the above explanation. // isolate the pattern rightOnesPattern = x ^ nextHigherOneBit; // right adjust pattern rightOnesPattern = (rightOnesPattern)/rightOne; // correction factor rightOnesPattern >>= 2; // rightOnesPattern is now part [A] of the above explanation. // integrate new pattern (Add [D] and [A]) next = nextHigherOneBit | rightOnesPattern; } return next; } void pre() { const int MAX_BITS = 18; SAME_BITCOUNT_NUMBERS.resize(MAX_BITS); for (int bits=1; bits <= MAX_BITS; bits++) { //printf("%d bits: ", bits); int number = (1 << bits) - 1; while (number < 130000) { //printf("%d ", number); SAME_BITCOUNT_NUMBERS[bits].push_back(number); number = next_same_bits(number); } //printf("\n"); } } int main() { pre(); int n; scanf("%d", &n); vector<int> v; initialVector(n, v); //verify(v, n); cout << v.size() << "\n"; //reverse(v.begin(), v.end()); for (int i=0; i < v.size(); i++) { printf("%d ", v[i]); } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | #include <iostream> #include <vector> #include <algorithm> #include <set> #include <math.h> #include <stdio.h> #include <deque> #include <unordered_map> #include <cassert> #include <numeric> #include <queue> #include <list> #include <string> #include <stack> #define LL long long #define MOD 1000000007 using namespace std; vector<vector<int> > SAME_BITCOUNT_NUMBERS; int bruteFindFirstGreaterThan(int x, int bits, int maxmax) { int y = x+1; while (__builtin_popcount(y) != bits) { y++; if (y>=maxmax || y > 130000) return y; } return y; } int findFirstGreaterThan(int x, int bits, int maxmax) { vector<int> &v = SAME_BITCOUNT_NUMBERS[bits]; auto it = lower_bound(v.begin(), v.end(), x); while (it != v.end()) { if (*it > x) return *it; ++it; } //assert(false); return 130000; } void initialVector(const int requiredBits, vector<int> &v) { const int INF = 1000010; vector<int> dp(requiredBits+1, INF); int i = 0; dp[0] = 0; dp[1] = 1; int bits = 1; for (int i=2;;i++) { bits += __builtin_popcount(i); //printf("bits=%d\n", bits); if (bits > requiredBits) break; dp[bits] = i; } //printf("before: "); for (int i=1; i <= requiredBits; i++) printf("dp[%d]=%d\n", i, dp[i]); for (int i=2; i <= requiredBits; i++) { if (dp[i] != INF) continue; for (int j=1; j < 18 && j <= i-1; j++) { int candidate = findFirstGreaterThan(dp[i-j], j, dp[i]); //printf("i:%d, candidate:%d\n", i, candidate); dp[i] = min(dp[i], candidate); } } //printf("after:\n"); for (int i=1; i <= requiredBits; i++) printf("dp[%d]=%d\n", i, dp[i]); v.clear(); bits = requiredBits; while (bits) { int prev = dp[bits]; v.push_back(prev); bits -= __builtin_popcount(prev); } return; } bool verify(const vector<int> &v, const int requiredBits) { int res = __builtin_popcount(v[0]); for (int i=1; i < v.size(); i++) { assert (v[i-1] > v[i]); res += __builtin_popcount(v[i]); } assert (res == requiredBits); //printf("all good\n"); return res == requiredBits; } #define uint_t unsigned int uint_t next_same_bits(uint_t x) { uint_t rightOne; uint_t nextHigherOneBit; uint_t rightOnesPattern; uint_t next = 0; if(x) { // right most set bit rightOne = x & -(signed)x; // reset the pattern and set next higher bit // left part of x will be here nextHigherOneBit = x + rightOne; // nextHigherOneBit is now part [D] of the above explanation. // isolate the pattern rightOnesPattern = x ^ nextHigherOneBit; // right adjust pattern rightOnesPattern = (rightOnesPattern)/rightOne; // correction factor rightOnesPattern >>= 2; // rightOnesPattern is now part [A] of the above explanation. // integrate new pattern (Add [D] and [A]) next = nextHigherOneBit | rightOnesPattern; } return next; } void pre() { const int MAX_BITS = 18; SAME_BITCOUNT_NUMBERS.resize(MAX_BITS); for (int bits=1; bits <= MAX_BITS; bits++) { //printf("%d bits: ", bits); int number = (1 << bits) - 1; while (number < 130000) { //printf("%d ", number); SAME_BITCOUNT_NUMBERS[bits].push_back(number); number = next_same_bits(number); } //printf("\n"); } } int main() { pre(); int n; scanf("%d", &n); vector<int> v; initialVector(n, v); //verify(v, n); cout << v.size() << "\n"; //reverse(v.begin(), v.end()); for (int i=0; i < v.size(); i++) { printf("%d ", v[i]); } return 0; } |