概率+容斥
题目链接:https://codeforces.com/problemset/problem/1187/F
首先考虑单点贡献,是\(a[i] != a[i + 1]\)的时候产生的。而我们知道\(E(x_1) + E(x_2) = E(x_1 + x_2)\)
所以如果没有平方我们只需要计算单点期望然后加起来,这就是\(p[i] = 1 - \frac{x}{b[i]}\times \frac{1}{b[i+1]}\), \(b[i] = r[i] - l[i] + 1\)
有平方的时候分为三种情况考虑\(E(x_i)E(x_j)\)
- i=j ,不需要平方
- |i-j|>1,相互独立可以直接算
- |i-j|=1, 这里就需要容斥,但是注意到边界因为点1和0处固定产生贡献,所以初始化p[1] = 1, 且0,1,2三点是独立的,所以可以不需要容斥(这里卡了一下)
code:
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
#define int long long
const int N = 2e5 + 7, mod = 1e9 + 7;
int read() {
int res = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
return res * f;
}
int add(int a, int b) {
return (a + b) % mod ;
}
int mul(int a, int b) {
return 1ll * a * b % mod;
}
int sub(int a, int b) {
return (a+mod-b)%mod;
}
int qpow(int x, int y) {
int res = 1;
while(y) {
if (y & 1) res = mul(res, x);
x = mul(x, x);
y >>= 1;
}
return res;
}
struct Node {
int l=0, r=0;
}a[N];
int p[N], q[N], pre[N], ans;
void calc(int i) {
int tmp = 0;
if (i - 2 > 0){
tmp = max(0ll, min({a[i].r, a[i - 1].r, a[i - 2].r}) - max({a[i].l, a[i - 1].l, a[i - 2].l}));
// cout << tmp << endl;
tmp = mul(tmp, qpow(mul(mul(a[i].r - a[i].l, a[i - 1].r - a[i - 1].l), a[i - 2].r - a[i - 2].l), mod - 2));
tmp = max(0ll, tmp);
}
int rc = add(sub(sub(1, q[i]), q[i - 1]), tmp);
ans = add(ans, rc);
}
void solve() {
int n;
cin >> n;
ans = 0;
for (int i = 1; i <= n ;i++) cin >> a[i].l;
for (int i = 1; i <= n ;i++) cin >> a[i].r, a[i].r++;
p[1] = 1;
pre[1] = 1;
for (int i = 2; i <= n ;i++) {
int tmp = max(0ll, min(a[i].r, a[i - 1].r) - max(a[i].l, a[i - 1].l));
// cout << "!!!"<<tmp << ' ' << mul(a[i].r - a[i].l, a[i - 1].r - a[i - 1].l) << endl;
q[i] = mul(tmp, qpow(mul(a[i].r - a[i].l, a[i - 1].r - a[i - 1].l), mod - 2));
p[i] = sub(1, q[i]);
pre[i] = add(pre[i - 1], p[i]);
// cout << p[i] << endl;
}
// cout << pre[n] << endl;
for (int i = 1; i <= n; i++) {
int cus = pre[n];
for (int j = max(1ll, i - 1); j <= min(n, i + 1); j++) {
cus = sub(cus, p[j]);
// cout <<j <<' '<<cus << endl;
}
ans = add(ans, mul(p[i], cus));
// cout << cus << endl;
if (i > 1) calc(i);
if (i < n) calc(i + 1);
ans = add(ans, p[i]);
}
// cout << mul(14, qpow(3, mod - 2)) << endl;;
cout << ans << endl;
}
signed main(){
int t = 1;
while(t--){
solve();
}
}

浙公网安备 33010602011771号