Random
Difficulty: Hard

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. 

Input Format:

Output Format:

Sample Input:

Sample Output:

Python 3 starter code:

Editorial: November 2020 Editorial - Random
<style id="MathJax_SVG_styles">.MathJax_SVG_Display {text-align: center; margin: 1em 0em; position: relative; display: block!important; text-indent: 0; max-width: none; max-height: none; min-width: 0; min-height: 0; width: 100%}
.MathJax_SVG .MJX-monospace {font-family: monospace}
.MathJax_SVG .MJX-sans-serif {font-family: sans-serif}
.MathJax_SVG {display: inline; font-style: normal; font-weight: normal; line-height: normal; font-size: 100%; font-size-adjust: none; text-indent: 0; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0; min-height: 0; border: 0; padding: 0; margin: 0}
.MathJax_SVG * {transition: none; -webkit-transition: none; -moz-transition: none; -ms-transition: none; -o-transition: none}
.mjx-svg-href {fill: blue; stroke: blue}
</style><svg style="display: none;"><defs id="MathJax_SVG_glyphs"></defs></svg><p>Here are the two atomic steps which need to be performed a number of times:  </p>

<p>1) Randomly choose two indexes (l, r) with l &lt; r and then swap (d[l], d[r]). <br>
2) Randomly choose two indexes (l, r) with l &lt; r and then reverse (d[l…r]) (both inclusive)  </p>

<p>We can calculate these two steps separately, because of the linearity of the expectation, we can calculate the expected array after the first step (repeated <em>a</em> times): (A[0], A[1], ..., A[n - 1]) and use this array as the input of the second step (repeated <em>b</em> times), then we can calculate the final answer based on the output at the end of the second step.    </p>

<p><strong>Solution for Step (1), i.e. swapping elements:</strong>  </p>

<p>How does one compute the expected value of the element in the i-th position after Step (1)? <br>
Let P(i, j, k) be the possibility that d[i] goes to the j-th position after executing Step (1) k times.   </p>

<p>A[i] = P(i, i, n1) * d[i] + sum(P(j, i, n1) * d[j] (i != j))  </p>

<p>// because all the operations are randomly chosen. <br>
P(i, i, k) = P(0, 0, k) <br>
P(j, i, k) = P(0, 1, k)  </p>

<p>==&gt; A[i] = P(0, 0, n1) * d[i] + P(0, 1, n1) * (sum - d[i])  </p>

<p>P(0, 1, n1) = P(0, 2, n1) = ... = P(0, n - 1, n1)  </p>

<p>and</p>

<p>P(0, 0, n1) + P(0, 1, n1) + ... + P(0, n - 1, n1) = P(0, 0, n1) + (n - 1) * P(0, 1, n1) = 1  </p>

<p>==&gt; P(0, 1, n1) = (1 - P(0, 0, n1)) / (n - 1).   </p>

<p>So we only need to calculate P(0, 0, n1).  </p>

<p>P(0, 0, k) = P(0, 0, k - 1) * P(unchanged) + P(0, 1, k - 1) * P(swap(0, 1)) + P(0, 2, k - 1) * P(swap(0, 2)) + ... + P(0, n - 1, k - 1) * P(swap(0, n - 1))  </p>

<p>Because P(0, 1, k) = P(0, 2, k) = ... = P(0, n - 1, k), P(swap(0, 1)) = P(swap(0, 2)) = ... = P(swap(0, n - 1))  </p>

<p>//P(swap(0, 1)) = 1 / C(n, 2)
//P(unchanged) + (n - 1) * P(swap(0, 1)) = 1   ==&gt;   P(unchanged) = (n - 2) / n. </p>

<p>==&gt; </p>

<p>P(0, 0, k) = P(0, 0, k - 1) * P(unchanged) + P(0, 1, k - 1) * P(swap(0, 1)) * (n - 1)
           = P(0, 0, k - 1) * P(unchanged) + (1 - P(0, 0, k - 1)) * P(swap(0, 1))
           = a * P(0, 0, k - 1) + b</p>

<p>F[k] = a * F[k - 1] + b</p>

<p>==&gt; F[k] + r = a * (F[k] + r) //geometric progression
==&gt; F[n1] + r = a ^ n1 * (1 + r)
==&gt; F[n1] = a ^ n1 * (1 + r) - r</p>

<p><strong>Solution for Step (2), i.e. reversing elements:</strong> <br>
Because n2 is relatively small, so we can calculate the expected output array after each operation. 
A0 A1 ... An-1
The first problem to solve is: after executing one random reverse, what is the expected output?
Similar to the first step, we only need to calculate the P(i, j): the possibility that Ai goes to the jth position.    </p>

<p>P(i, j) = number_of_reverse_intervals_swap_(i, j) / C(n, 2) <br>
number_of_reverse_intervals_swap_(i, j) = min(i + 1, n - j).   </p>

<h3>Solution:</h3>  

<pre><code>#include &lt;map&gt; 
#include &lt;set&gt; 
#include &lt;list&gt; 
#include &lt;cmath&gt; 
#include &lt;ctime&gt; 
#include &lt;stack&gt; 
#include &lt;queue&gt; 
#include &lt;vector&gt; 
#include &lt;cstdio&gt; 
#include &lt;string&gt; 
#include &lt;bitset&gt; 
#include &lt;climits&gt; 
#include &lt;cstdlib&gt; 
#include &lt;cstring&gt; 
#include &lt;utility&gt; 
#include &lt;sstream&gt; 
#include &lt;iostream&gt; 
#include &lt;algorithm&gt; 
#define sqr(x) ((x)*(x)) 
#define ABS(x) ((x&lt;0)?(-(x)):(x)) 
#define eps (1e-13)
#define mp make_pair 
#define pb push_back 
#define Pair pair&lt;int,int&gt; 
#define xx first 
#define yy second 
#define equal(a,b) (ABS((a)-(b))&lt;eps) 
using namespace std; 

template&lt;class T&gt; string tostring(T x) { ostringstream out; out&lt;&lt;x; return out.str();} 
long long toint(string s) { istringstream in(s); long long x; in&gt;&gt;x; return x; } 

int dx[8]={0, 0, 1,-1, 1, 1,-1,-1}; 
int dy[8]={1,-1, 0, 0,-1, 1,-1, 1}; 
int kx[8]={1, 1,-1,-1, 2, 2,-2,-2}; 
int ky[8]={2,-2, 2,-2, 1,-1, 1,-1}; 

///////////////////////////////////////////////////////////////////////////////////////////////////// 

int d[1000], n;
double p1, p2;

#define MAX 2

typedef struct matrix
{
    int row,col;
    double m[MAX][MAX];
    matrix(int r,int c,int k)
    {
        row=r;
        col=c;
        for (int i=0;i&lt;r;i++)
            for (int j=0;j&lt;c;j++)
                m[i][j]=k;
    }
    matrix(){}
} matrix;
matrix operator *(matrix a,matrix b)
{
    matrix c;
    double t;
    c.row=a.row; c.col=b.col;
    for (int i=0;i&lt;c.row;i++)
    for (int j=0;j&lt;c.col;j++)
    {
        t=0;
        for (int k=0;k&lt;a.col;k++)
        t=(t+a.m[i][k]*b.m[k][j]);
        c.m[i][j]=t;
    }
    return c;
}
matrix pow(matrix a,int k)
{
    matrix c;
    if (k==1) return a;
    c = pow(a, k / 2);
    c = c * c;
    if (k % 2 == 0) return c;
    else return c * a;
}

int ways(int cnt) {
    return cnt * (cnt - 1) / 2;
}

void calc(int cnt) {
    int tot = ways(n);
    matrix m(2, 2, 0);
    m.m[0][0] = (tot - n + 1.0) / tot; m.m[0][1] = (n - 1.0) / tot;
    m.m[1][0] = 1.0 / tot; m.m[1][1] = (tot - 1.0) / tot;

    m = pow(m, cnt);
    p1 = m.m[0][0];
    p2 = m.m[0][1];
}

double f[1000][1000]; // probability of j'th number being at i'th place after all operations
double g[1000][1000];


double sum1[1000][1001], sum2[1000][1001], sum3[1000][1001];
void calc2(int cnt) {
    memset(f, 0, sizeof(f));
    for (int i = 0; i &lt; n; i++)
        for (int j = 0; j &lt; n; j++)
            if (i == j) f[i][j] = p1;
            else f[i][j] = p2 / (n - 1);

    for (int iter = 0; iter &lt; cnt; iter++) {
        for (int c = 0; c &lt; n; c++) {
            sum1[c][0] = sum2[c][0] = sum3[c][0] = 0.0;
            for (int i = 0; i &lt; n; i++) {
                sum1[c][i + 1] = sum1[c][i] + f[i][c];
                sum2[c][i + 1] = sum2[c][i] + f[i][c] * (n - i) / (double) ways(n);
                sum3[c][i + 1] = sum3[c][i] + f[i][c] * (i + 1) / (double) ways(n);
            }
        }
        for (int i = 0; i &lt; n; i++) {
            for (int k = 0; k &lt; n; k++) {
                // same
                g[i][k] += f[i][k] * (min(n - 1 - i, i) + ways(i) + ways(n - 1 - i)) / (double) ways(n);
                if (n - i - 1 &gt; i) g[i][k] += (sum1[k][n - i] - sum1[k][i + 1]) * (i + 1) / (double) ways(n); // i + 1 .. n - i - 1
                if (n - i - 1 &lt; i) g[i][k] += (sum1[k][i] - sum1[k][n - i - 1]) * (n - i) / (double) ways(n); // n - i - 1 .. i - 1

                if (i != n - 1) g[i][k] += (sum2[k][n] - sum2[k][max(n - i - 1, i) + 1]); // max(n - i - 1, i)+1 .. n - 1
                if (i != 0) g[i][k] += (sum3[k][min(n - i - 1, i)]); // 0 .. min(n - i - 1, i) - 1
            }
        }      
        memcpy(f, g, sizeof(g));
        memset(g, 0, sizeof(g));
    }
}

int main() {
//    freopen("random.in", "r", stdin);
    int n1, n2;
    scanf("%d%d%d", &amp;n, &amp;n1, &amp;n2);
    for (int i = 0; i &lt; n; i++)
        scanf("%d", &amp;d[i]);
    calc(n1);
    calc2(n2);
    double res = 0.0;
    for (int i = 0; i &lt; n; i++) { // place
        double p = ((i + 1) * (n - i) - 1.0) / (n * (n - 1) / 2.0);
        for (int j = 0; j &lt; n; j++) // number
            res += d[j] * f[i][j] * p;
    }
    printf("%.9lf\n", res);
    return 0;
}
</code></pre>

Reference solution (C++):
###C++  
```cpp  

#include <map> 
#include <set> 
#include <list> 
#include <cmath> 
#include <ctime> 
#include <stack> 
#include <queue> 
#include <vector> 
#include <cstdio> 
#include <string> 
#include <bitset> 
#include <climits> 
#include <cstdlib> 
#include <cstring> 
#include <utility> 
#include <sstream> 
#include <iostream> 
#include <algorithm> 
#define sqr(x) ((x)*(x)) 
#define ABS(x) ((x<0)?(-(x)):(x)) 
#define eps (1e-13)
#define mp make_pair 
#define pb push_back 
#define Pair pair<int,int> 
#define xx first 
#define yy second 
#define equal(a,b) (ABS((a)-(b))<eps) 
using namespace std; 
 
template<class T> string tostring(T x) { ostringstream out; out<<x; return out.str();} 
long long toint(string s) { istringstream in(s); long long x; in>>x; return x; } 
 
int dx[8]={0, 0, 1,-1, 1, 1,-1,-1}; 
int dy[8]={1,-1, 0, 0,-1, 1,-1, 1}; 
int kx[8]={1, 1,-1,-1, 2, 2,-2,-2}; 
int ky[8]={2,-2, 2,-2, 1,-1, 1,-1}; 
 
///////////////////////////////////////////////////////////////////////////////////////////////////// 
    
int d[1000], n;
double p1, p2;
    
#define MAX 2
    
typedef struct matrix
{
    int row,col;
    double m[MAX][MAX];
    matrix(int r,int c,int k)
    {
        row=r;
        col=c;
        for (int i=0;i<r;i++)
            for (int j=0;j<c;j++)
                m[i][j]=k;
    }
    matrix(){}
} matrix;
matrix operator *(matrix a,matrix b)
{
    matrix c;
    double t;
    c.row=a.row; c.col=b.col;
    for (int i=0;i<c.row;i++)
    for (int j=0;j<c.col;j++)
    {
        t=0;
        for (int k=0;k<a.col;k++)
        t=(t+a.m[i][k]*b.m[k][j]);
        c.m[i][j]=t;
    }
    return c;
}
matrix pow(matrix a,int k)
{
    matrix c;
    if (k==1) return a;
    c = pow(a, k / 2);
    c = c * c;
    if (k % 2 == 0) return c;
    else return c * a;
}
    
int ways(int cnt) {
    return cnt * (cnt - 1) / 2;
}
    
void calc(int cnt) {
    int tot = ways(n);
    matrix m(2, 2, 0);
    m.m[0][0] = (tot - n + 1.0) / tot; m.m[0][1] = (n - 1.0) / tot;
    m.m[1][0] = 1.0 / tot; m.m[1][1] = (tot - 1.0) / tot;
    
    m = pow(m, cnt);
    p1 = m.m[0][0];
    p2 = m.m[0][1];
}
    
double f[1000][1000]; // probability of j'th number being at i'th place after all operations
double g[1000][1000];
    
    
double sum1[1000][1001], sum2[1000][1001], sum3[1000][1001];
void calc2(int cnt) {
    memset(f, 0, sizeof(f));
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            if (i == j) f[i][j] = p1;
            else f[i][j] = p2 / (n - 1);
    
    for (int iter = 0; iter < cnt; iter++) {
        for (int c = 0; c < n; c++) {
            sum1[c][0] = sum2[c][0] = sum3[c][0] = 0.0;
            for (int i = 0; i < n; i++) {
                sum1[c][i + 1] = sum1[c][i] + f[i][c];
                sum2[c][i + 1] = sum2[c][i] + f[i][c] * (n - i) / (double) ways(n);
                sum3[c][i + 1] = sum3[c][i] + f[i][c] * (i + 1) / (double) ways(n);
            }
        }
        for (int i = 0; i < n; i++) {
            for (int k = 0; k < n; k++) {
                // same
                g[i][k] += f[i][k] * (min(n - 1 - i, i) + ways(i) + ways(n - 1 - i)) / (double) ways(n);
                if (n - i - 1 > i) g[i][k] += (sum1[k][n - i] - sum1[k][i + 1]) * (i + 1) / (double) ways(n); // i + 1 .. n - i - 1
                if (n - i - 1 < i) g[i][k] += (sum1[k][i] - sum1[k][n - i - 1]) * (n - i) / (double) ways(n); // n - i - 1 .. i - 1
    
                if (i != n - 1) g[i][k] += (sum2[k][n] - sum2[k][max(n - i - 1, i) + 1]); // max(n - i - 1, i)+1 .. n - 1
                if (i != 0) g[i][k] += (sum3[k][min(n - i - 1, i)]); // 0 .. min(n - i - 1, i) - 1
            }
        }      
        memcpy(f, g, sizeof(g));
        memset(g, 0, sizeof(g));
    }
}
    
int main() {
//    freopen("random.in", "r", stdin);
    int n1, n2;
    scanf("%d%d%d", &n, &n1, &n2);
    for (int i = 0; i < n; i++)
        scanf("%d", &d[i]);
    calc(n1);
    calc2(n2);
    double res = 0.0;
    for (int i = 0; i < n; i++) { // place
        double p = ((i + 1) * (n - i) - 1.0) / (n * (n - 1) / 2.0);
        for (int j = 0; j < n; j++) // number
            res += d[j] * f[i][j] * p;
    }
    printf("%.9lf\n", res);
    return 0;
}
```