/* * Sample solution for Bit Counting * Steven J Zeil, 10/21/2010 */ #include #include using namespace std; int kSteps[64]; // kSteps[i] number of steps to converge to 1 starting with i long long unsigned bitDistribution[64][64]; // bitDistribution[i][j] = # of numbers in the range 0..2^i-1 that // have j one bits in their representation // The pattern is familiar: // 1 // 1 1 // 1 2 1 // 1 3 3 1 // etc. unsigned numOnesIn (unsigned long long m) { unsigned cnt = 0; while (m > 0) { if (m % 2LLU == 1LLU) ++cnt; m = m / 2LLU; } return cnt; } unsigned basicStepCount (unsigned int m) { unsigned k = 0; if (m > 1LLU) { unsigned n = numOnesIn(m); ++k; while (n > 1) { n = numOnesIn(n); ++k; } return k; } else return 1; } void setup() { kSteps[0] = kSteps[1] = 0; for (unsigned int i = 2; i < 64; ++i) kSteps[i] = basicStepCount(i); for (int j = 0; j < 64; ++j) bitDistribution[0][j] = 0; bitDistribution[0][0] = 1; for (int i = 1; i < 64; ++i) { bitDistribution[i][0] = 1; for (int j = 1; j < 64; ++j) bitDistribution[i][j] = bitDistribution[i-1][j-1] + bitDistribution[i-1][j]; } } unsigned distributeNumberByBits (unsigned long long m, unsigned long long* distribution) { int power = 0; int numOnesSoFar = numOnesIn(m); fill_n (distribution, 64, 0LLU); distribution[0] = 1; while (m > 0LLU) { //cerr << "m " << m << "\tpower " << power << endl; if (m % 2LLU == 1LLU) { --numOnesSoFar; //cerr << "checking 0..2^" << power << endl; // 2^power has one one-bit (plus however many bits appear to the left) ++(distribution[1+numOnesSoFar]); // Add in the number of ints from 0..2^power-1 for (int bits = 1; bits <= power+1; ++bits) { unsigned long long numNumbers = bitDistribution[power][bits]; distribution[bits+numOnesSoFar] += numNumbers; } } ++power; m = m / 2LLU; } } unsigned long long stepCountInRange (unsigned long long m, unsigned desiredK) { unsigned long long count = 0LLU; unsigned long long numbersByBitCount[64]; distributeNumberByBits (m, numbersByBitCount); /* // Sanity check long long unsigned count2 = 0; for (int i = 0; i < 64; ++i) count2 += numbersByBitCount[i]; if (count2 != m+1LLU) cerr << "**Inconsistency detected for m =" << m << ": " << count2 << endl; cerr << "In the range 0.." << m << " the numbers are distributed as\n"; for (int i = 0; i < 16; ++i) cerr << numbersByBitCount[i] << ' '; cerr << endl; */ for (int bits = 0; bits < 64; ++bits) if (kSteps[bits] + 1 == desiredK) count += numbersByBitCount[bits]; // Special case: K(1) == 0, but the above caculation treats it as 1 if (m >= 1UL) { if (desiredK == 0) ++count; else if (desiredK == 1) --count; } return count; } void bitcounting (unsigned long long lo, unsigned long long hi, unsigned k) { unsigned long long cnt1 = stepCountInRange(lo-1LLU, k); unsigned long long cnt2 = stepCountInRange(hi, k); cout << cnt2-cnt1 << endl; } int main (int argc, char** argv) { setup(); while (cin) { unsigned long long lo, hi; unsigned k; cin >> lo >> hi >> k; //cout << lo << " " << hi << " " << k << endl; if (lo == 0L) break; bitcounting (lo, hi, k); } return 0; }