首先有贪心。概率大的匹配大的数字。
定义 为从数字
到
的期望步数。
有
然后画出矩阵。其中,,省略了一列
。
考虑高斯消元。
设 为矩阵的第
行,则
从
到
,依次执行
。
下面的矩阵都是经过上述变换的。
是第
行的常数项,则
当 ,
。
否则,你可以通过查公式或换元 来得到
。
最终, 形如
。
于是 。
然后考虑倒推到 。
,于是
,进而
。
当 时,
。
否则,。
较官解的优点在于不依赖 的限制,且复杂度更优。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, l, r) for(int i = (l); i <= (r); ++i)
#define per(i, r, l) for(int i = (r); i >= (l); --i)
const int N = 2e5 + 5, mod = 1e9 + 7;
ll qpow(ll a, ll p) {
a %= mod;
ll ans = 1;
while (p) {
if (p & 1) ans = ans * a % mod;
a = a * a % mod;
p >>= 1;
}
return ans;
}
int n, p[N << 1];
ll calc(int p, int n) {
if (p * 2LL % mod == 1) {
ll st = 1LL * (n + 1) * n % mod;
return st;
}
ll _p = (1 + mod - p) % mod, ivp = qpow(p, mod - 2);
ll a = _p * ivp % mod;
ll st = (n - (1 - qpow(a, n) + mod) % mod * a % mod * qpow((1 - a + mod) % mod, mod - 2) % mod + mod) % mod * qpow((1 - a + mod) % mod, mod - 2) % mod * ivp % mod;
return st;
}
void Sol() {
cin >> n;
rep(i, 1, n * 2) cin >> p[i];
sort(p + 1, p + n * 2 + 1);
ll ans = 0;
rep(i, 1, 2 * n) p[i] = 1LL * p[i] * qpow(100, mod - 2) % mod;
rep(i, 1, 2 * n) ans = (ans + calc(p[i], (i + 1) / 2)) % mod;
cout << ans << '\n';
}
int main() {
cin.tie(0), cout.tie(0), ios::sync_with_stdio(0);
int T = 1;
while(T--) Sol();
return 0;
}