Challenge: Random Integers Random Bits
Subdomeniu: Probability (probability)
Scor cont: 60.0 / 60
Submission status: Accepted
Submission score: 1.0
Submission ID: 464756904
Limbaj: cpp14
Link challenge: https://www.hackerrank.com/challenges/rirb/problem
Cerinta
Given an integer range [A,B],
1. What’s the probability to get a 1-bit if we first randomly choose a number x in the range and then randomly choose a bit from x?
2. What’s the expected number of bit 1s if we randomly choose a number x in the range?
**Input Format**
The first line of input is the number of test cases $T$
Each test cases is a line contains 2 integers $A$ and $B$ separated by a space.
**Output Format**
For each test case output a line containing 2 float numbers separated by a space. The first one is the probability and the second one is the expected number. You should output the number accurate to 5 fractional digits.
**Constraints**
$1 \le T \le 200$
$1 \le A \le B \le 10^{10}$
**Sample Input**
1
2 4
**Sample Output**
0.61111 1.33333
**Explanation**
(10) (11) (100)
(1) So we got a one in $\frac{1}{3} \times \frac{1}{2} + \frac{1}{3} \times \frac{1}{1} + \frac{1}{3} \times \frac{1}{3} = \frac{11}{18}$
(2) The expected 1 we have is : $1 \times \frac{1}{3} + 2 \times \frac{1}{3} + 1 \times \frac{1}{3} = \frac{4}{3}$
Cod sursa
#include <bits/stdc++.h>
using namespace std;
using i128 = __int128_t;
using u128 = __uint128_t;
static inline i128 prefixPopcount(unsigned long long n) {
// sum_{x=0..n} popcount(x)
i128 total = 0;
u128 nn = (u128)n + 1; // count of numbers
for (int b = 0; b < 64; ++b) {
u128 half = (u128)1 << b;
u128 cycle = half << 1;
if (half > nn && b > 0) {
// for larger b, term will be 0
if (((u128)1 << b) > nn && ((u128)1 << (b + 1)) > nn) {
// keep loop simple; break when half exceeds nn and no remainder can add
}
}
u128 full = nn / cycle;
u128 rem = nn % cycle;
u128 ones = full * half + (rem > half ? rem - half : 0);
total += (i128)ones;
if (half > nn) break;
}
return total;
}
static inline long double prefixRatio(unsigned long long n) {
// sum_{x=1..n} popcount(x) / bitlen(x)
if ((long long)n <= 0) return 0.0L;
long double ans = 0.0L;
for (int L = 1; L <= 64; ++L) {
u128 l = (L == 1 ? 1 : ((u128)1 << (L - 1)));
if (l > (u128)n) break;
u128 r = ((u128)1 << L) - 1;
if (r > (u128)n) r = (u128)n;
unsigned long long ll = (unsigned long long)l;
unsigned long long rr = (unsigned long long)r;
i128 ones = prefixPopcount(rr) - prefixPopcount(ll - 1);
ans += (long double)ones / (long double)L;
}
return ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
cout.setf(std::ios::fixed);
cout << setprecision(5);
while (T--) {
unsigned long long A, B;
cin >> A >> B;
unsigned long long cnt = B - A + 1;
i128 sumOnes = prefixPopcount(B) - (A == 0 ? 0 : prefixPopcount(A - 1));
long double expected = (long double)sumOnes / (long double)cnt;
long double sumRatio = prefixRatio(B) - (A == 0 ? 0.0L : prefixRatio(A - 1));
long double prob = sumRatio / (long double)cnt;
cout << (double)prob << ' ' << (double)expected << '\n';
}
return 0;
}
HackerRank Probability – Random Integers Random Bits
