2022ICPC昆明 C题-Cup of Water 题解

题意: T ( T < = 10000 ) T (T<=10000) T(T<=10000) 组询问 , 每组给定 x ( 0.05 ≤ x ≤ 1 e 9 ) x (0.05 \le x \le 1e9) x(0.05x1e9) . 每次从 [ 0 , x ] [0,x] [0,x] 随机抽一个实数,累加这些实数,直到和 ≥ 1 \ge 1 1 停止抽。求抽取次数的期望。

思路:
step1 :
记抽取次数为 k k k, P ( k = i ) = P ( k ≥ i ) − P ( k ≥ i + 1 ) P (k=i) = P(k \ge i)-P(k \ge i+1) P(k=i)=P(ki)P(ki+1) 。我们只需计算出所有 P ( k ≥ i ) P(k \ge i) P(ki)即可。
进一步化简, ∑ i = 1 ∞ i ∗ P ( k = i ) = ∑ i = 1 ∞ P ( k ≥ i ) \sum\limits_{i=1}^\infty i*P(k=i) = \sum\limits_{i=1}^\infty P(k\ge i) i=1iP(k=i)=i=1P(ki)
step2 :
P ( k ≥ i + 1 ) P(k \ge i+1) P(ki+1) = P ( 抽取 i 次仍 < 1 ) P(抽取i次仍 < 1) P(抽取i次仍<1) = P ( ∑ j = 1 i x j < 1 ) , 0 < x j < x P(\sum\limits_{j=1}^ix_j < 1),0<x_j<x P(j=1ixj<1),0<xj<x
首先考虑简单点的情况 x > 1 x>1 x>1
i = 1 i=1 i=1 : P ( 抽取 i 次仍 < 1 ) P(抽取i次仍 < 1) P(抽取i次仍<1) = 1 / x 1/x 1/x ; 长度为1.
i = 2 i=2 i=2 : P ( 抽取 i 次仍 < 1 ) P(抽取i次仍 < 1) P(抽取i次仍<1) = 1 / ( 2 ∗ x 2 ) 1/(2*x^2) 1/(2x2) ; 三角形面积为1/2.
i = 2 i=2 i=2 : P ( 抽取 i 次仍 < 1 ) P(抽取i次仍 < 1) P(抽取i次仍<1) = 1 / ( 6 ∗ x 3 ) 1/(6*x^3) 1/(6x3) ; 三棱锥体积为1/6.
猜测出结论: ∑ j = 1 i x j < l e n \sum\limits_{j=1}^ix_j < len j=1ixj<len 作为 i i i重积分区域时,测度为 l e n i i ! \frac{len^i}{i!} i!leni ( 0 < x j < x 且 x > l e n ) (0<x_j<x且x>len) 0<xj<xx>len
此式记为 f ( l e n ) f(len) f(len);
step3:
x < 1 x<1 x<1: 问题在于计算出 ∑ j = 1 i x j < 1 ( 0 < x j < x ) \sum\limits_{j=1}^ix_j < 1(0<x_j<x) j=1ixj<10<xj<x的测度。
我们要利用step2中的测度公式,那么不妨先将每个抽取的 x j x_j xj的范围扩大到[0, ∞ \infty ] 。
假设 i i i 个数中有 j j j 个数 > x > x >x 的测度为 a n s j ans_j ansj 。 我们要计算 a n s 0 ans_0 ans0
可以用容斥来解决。
j j j 个数 > x >x >x ,其余数范围不限(即为[0, ∞ \infty ] )。把这 j j j 个数的 a a a 从总和中剔除掉,则选定一组 j j j 个数后,测度为 f ( 1 − j a ) f(1-ja) f(1ja)。(前提是 1 − j a > 0 1-ja>0 1ja>0
f ( 1 − j a ) ∗ C ( n , j ) = C ( j , j ) ∗ a n s j + C ( j + 1 , j ) ∗ a n s j + 1 + C ( j + 2 , j ) ∗ a n s j + 2 + . . . . . f(1-ja)*C(n,j)=C(j,j)*ans_j+C(j+1,j)*ans_{j+1}+C(j+2,j)*ans_{j+2}+..... f(1ja)C(n,j)=C(j,j)ansj+C(j+1,j)ansj+1+C(j+2,j)ansj+2+.....
a n s 0 ans_0 ans0可用容斥计算,结果为 ∑ j = 0 m i n ( i , 1 / a ) ( − 1 ) j ( 1 − j x ) i j ! ( i − j ) ! \sum\limits_{j=0}^{min(i,1/a)} \frac{(-1)^j(1-jx)^i}{j! (i-j)!} j=0min(i,1/a)j!(ij)!(1)j(1jx)i
概率还要除以总测度,即 x i x^i xi
最终答案: ∑ i = 0 ∞ ∑ j = 0 m i n ( i , 1 / a ) ( − 1 ) j j ! ( i − j ) ! ( 1 − j x x ) i \sum\limits_{i=0}^\infty \sum\limits_{j=0}^{min(i,1/a)} \frac{(-1)^j}{j! (i-j)!} (\frac{1-jx}{x})^i i=0j=0min(i,1/a)j!(ij)!(1)j(x1jx)i
这样其实就可以AC了(无穷取TLE以内的足够,精度要求不高)。
不过我们可以进一步化简,变换求和次序:
∑ j = 0 1 / a ∑ i = j ∞ ( − 1 ) j j ! ( i − j ) ! ( 1 − j x x ) i \sum\limits_{j=0}^{1/a} \sum\limits_{i=j}^\infty \frac{(-1)^j}{j! (i-j)!} (\frac{1-jx}{x})^i j=01/ai=jj!(ij)!(1)j(x1jx)i = ∑ j = 0 1 / a ∑ i = j ∞ ( − 1 ) j j ! ( 1 − j x x ) j e x p ( 1 − j x x ) \sum\limits_{j=0}^{1/a} \sum\limits_{i=j}^\infty \frac{(-1)^j}{j!} (\frac{1-jx}{x})^j exp(\frac{1-jx}{x}) j=01/ai=jj!(1)j(x1jx)jexp(x1jx)

Code:

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=j;i<=k;++i)
#define per(i,j,k) for(int i=j;i>=k;--i)
#define IOS {cin.tie(0); cout.tie(0); ios::sync_with_stdio(0);}
#define ll long long
#define P pair<int,int>
#define vi vector<int>
#define ls i<<1,l,mid
#define rs i<<1|1,mid+1,r
#define mi int mid=(l+r)>>1;
#define db double
#define ld long double
int T;double x;
const int N=25;
ld fac[N];
int main(){
    IOS
    fac[0]=1;
    rep(i,1,24)fac[i]=i*fac[i-1];
    cin>>T;
    while(T--){
        cin>>x; ld ans=0;
        for(int j=0,f=-1;;++j){
            if(1-j*x<0)break;
            f=-f;
            ans+=f*pow((1-j*x)/x,j)*exp((1-j*x)/x)/fac[j];
        }
        cout<<fixed<<setprecision(10)<<db(ans)<<'\n';
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值