Challenge: Random
Subdomeniu: Probability (probability)
Scor cont: 100.0 / 100
Submission status: Accepted
Submission score: 1.0
Submission ID: 464737292
Limbaj: cpp14
Link challenge: https://www.hackerrank.com/challenges/random/problem
Cerinta
Given an array 'D' with n elements: d[0], d[1], ..., d[n-1], you can perform the following two steps on the array.
1. Randomly choose two indexes (l, r) with l < r, swap (d[l], d[r])
2. Randomly choose two indexes (l, r) with l < r, reverse (d[l...r]) (both inclusive)
After you perform the first operation **a** times and the second operation **b** times, you randomly choose two indices _l_ & _r_ with _l_ < _r_ and calculate the S = sum(d[l...r]) (both inclusive).
Now, you are to find the expected value of S.
**Input Format**
The first line of the input contains 3 space separated integers - n, a and b.
The next line contains n space separated integers which are the elements of the array *d*.
n a b
d[0] d[1] ... d[n-1]
**Output Format**
Print the expected value of S.
E(S)
**Constraints**
2 <= n <= 1000
1 <= a <= 10<sup>9</sup>
1 <= b <= 10
The answer will be considered correct, if the absolute or relative error doesn't exceed 10<sup>-4</sup>.
**Sample Input #00:**
3 1 1
1 2 3
**Sample Output #00:**
4.666667
**Explanation #00:**
At step 1):
You have three choices:
1. swap(0, 1), 2 1 3
2. swap(0, 2), 3 2 1
3. swap(1, 2), 1 3 2
At step 2):
For every result you have three choices for reversing:
1. [2 1 3] -> [1 2 3] [3 1 2] [2 3 1]
2. [3 2 1] -> [2 3 1] [1 2 3] [3 1 2]
3. [1 3 2] -> [3 1 2] [2 3 1] [1 2 3]
So you have 9 possible arrays with each having a 1/9 probability.
For the last step:
Each of the 9 arrays will have 3 possible sums with equal probability. For [1 2 3], you can get 1+2, 2+3 and 1+2+3.
Since there will be 27 outcome for this input, one can calculate the expected value by finding sum of all 27 S and dividing it by 27.
Cod sursa
#include <algorithm>
#include <cstdio>
#define MAX_N 1000
using namespace std;
float g[MAX_N][MAX_N], h[2][MAX_N];
int k[MAX_N], d[MAX_N];
int remove_space() {
int ch;
while (true) {
ch = getchar_unlocked();
if (ch != ' ' && ch != '\n')
break;
}
return ch;
}
template<typename T> T read_unsigned_integer() {
T result = (T) 0;
int ch = remove_space();
while (ch >= '0' && ch <= '9') {
result = 10 * result + (ch - '0');
ch = getchar_unlocked();
}
return result;
}
template<typename T> T read_signed_integer() {
T result = (T) 0;
bool flip = false;
int ch = remove_space();
if (ch == '-') {
flip = true;
ch = remove_space();
}
while (ch >= '0' && ch <= '9') {
result = 10 * result + (ch - '0');
ch = getchar_unlocked();
}
return flip ? -result : result;
}
pair<float, float> get_pair(pair<float, float> x, pair<float, float> y) {
float q = x.second * y.second;
float p = (x.first + x.second) * (y.first + y.second) - q;
return make_pair(p, q);
}
pair<float, float> get_pow(pair<float, float> x, int e) {
pair<float, float> result(0.0f, 1.0f);
pair<float, float> base = x;
if (e > 0) {
while (true) {
if (e & 1) {
result = get_pair(result, base);
}
e >>= 1;
if (e <= 0)
break;
base = get_pair(base, base);
}
}
return result;
}
void solve() {
int n, a, b;
n = read_unsigned_integer<int>();
a = read_unsigned_integer<int>();
b = read_unsigned_integer<int>();
for (int i = 0; i < n; i++)
d[i] = read_signed_integer<int>();
float s = 2.0f / (n - 1) , t = (float) (n - 3) / (n - 1);
pair<float, float> coef = get_pow(make_pair(s, t), a);
coef.first /= n;
int m = n * (n - 1) / 2;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
int l = min(i, j) + 1;
int r = n - max(i, j);
int x = min(l, r) - (i == j);
k[j] += x;
if (i == j)
x += i * (i - 1) / 2 + (n - 1 - i) * (n - 1 - i - 1) / 2;
g[i][j] = (float) x / m;
}
long long sum = 0;
for (int i = 0; i < n; i++) {
sum += d[i];
h[0][i] = d[i];
}
int p = 0;
for (int k = 0; k < b; k++) {
float *alpha = h[p];
p ^= 1;
float *beta = h[p];
for (int i = 0; i < n; i++) {
beta[i] = 0.0;
for (int j = 0; j < n; j++)
beta[i] += g[i][j] * alpha[j];
}
}
for (int i = 0; i < n; i++)
h[p][i] = coef.first * sum + coef.second * h[p][i];
float result = 0.0;
for (int i = 0; i < n; i++)
result += k[i] * h[p][i];
result /= m;
printf("%f\n", result);
}
int main() {
solve();
return 0;
}
HackerRank Probability – Random
