随机+硬核积分+前缀和——ICPC NCNA 2018 H

有一个结论:在线段(长为L)上任取两点,截取的线段期望长度是L/3

 知道这个结论后这题就可以做了

但还是要分类大讨论+公式化简,用前缀和做

#include <bits/stdc++.h>
#define _for(i,a,b) for(int i=a;i<b;++i)
#define _rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
typedef long long LL;
typedef long double LD;
const int MAX
N = 1e5 + 10;
const LD eps
= 1e-10;
LD L[MAXN], R[
MAXN], mid
[MAXN], summ
id[MAXN], len
[MAXN], tlen[
MAXN][4];
LL n;
int main() {
scanf("%lld", &n);
_rep(i, 1, n) {
scanf("%Lf%Lf", &L[i], &R[i]);
mid[i] = (L[i] + R[i]) / 2;
len[i] = R[i] - L[i];
summid[i] = summid[i - 1] + mid[i];

LD temp = 1;
for (nt j = 0; j < 4; ++j) {
temp *= R[i];
}
}

LD ans = 0;
_rep(i, 1, n) {
ans += (i - 1)*mid[i] - summid[i - 1];
if (len[i] < eps) continue;
int pos = upper_bound(R + 1, R + 1 + n, L[i]) - R;
LD temp = 1;
ans += temp / len[i] * (tlen[i - 1][3] - tlen[pos - 1][3]) / 3;
temp *= L[i];
ans -= temp / len[i] * (tlen[i - 1][2] - tlen[pos - 1][2]);
temp *= L[i];
ans += temp / len[i] * (tlen[i - 1][1] - tlen[pos - 1][1]);
temp *= L[i];
ans -= temp / len[i] * (tlen[i - 1][0] - tlen[pos - 1][0]) / 3;
}
printf("%.9Lf ", ans / n / n);
return 0;
}

原文地址:https://www.cnblogs.com/zsben991126/p/12811533.html