LG P5147 随机数生成器

题目描述

HKE最近编写了一个函数 ( ext{rand}(l,r)),其中 (l,r) 为正整数且 (l le r)。这个函数会等概率返回区间 ([l,r]) 中任意一个正整数。然后,他又编写了一个函数:

int work(int x){
    if(x==1) return 0;
    else return work(rand(1,x))+1;
}

现在给定一个正整数 (n),请问 ( ext{work}(n)) 的返回值的期望值是多少?对于(70\%)的数据,(nle 10^6),对于(100\%)的数据,(n<2^{31})

分析

(f_i)( ext{work}(i))的期望,那么

[f_i=dfrac1{i}sum_{j=1}^i f_j+1 ]

边界(f_1=0)。记(S_i)(f_i)的前(i)项和,则

[f_i=dfrac1iS_i+1 ]

同理有(f_{i-1}=dfrac1iS_{i-1}+1)。将两式相减得

[if_i-(i-1)f_{i-1}=S_i-S_{i-1}+1 ]

整理即得

[f_i=f_{i-1}+dfrac1{i-1} ]

从而

[f_i=sum_{j=1}^{i-1}+1=H_{i-1}+1 ]

其中(H_{i-1})为第(i-1)项调和数。

对于(70\%)的数据,可以(O(n))递推(f_n)。注意到当(n)充分大时,有(H_napprox ln n+gamma),其中(gammaapprox 0.57721566490153286)为欧拉常数,(O(1))即可计算。

Code

#include <cstdio>
#include <iostream>
#include <cmath>

using namespace std;

const double g=0.57721566490153286;

double sum;
int n;

int main()
{
      scanf("%d",&n);

      if(n<=1e6)
            for(int i=1;i<=n-1;++i)
                  sum+=1.0/i;
      else
            sum=log(n)+g;

      printf("%.5lf
",n==1?0:sum+1.0);
}
原文地址:https://www.cnblogs.com/Anverking/p/13935231.html