zoukankan      html  css  js  c++  java
  • [洛谷P5147]随机数生成器

    题目大意:
    $$
    f_n=
    egin{cases}
    frac{sumlimits_{i=1}^nf_i}n+1&(n>1)\
    0&(n=1)
    end{cases}
    $$
    求$f_n(n<2^{31})$

    题解:考虑$n>2$时的情况。

    $$
    f_n=dfrac{sumlimits_{i=1}^nf_i}n+1\
    nf_n=sumlimits_{i=1}^{n-1}f_i+f_n+n\
    egin{align}
    (n-1)f_n=sumlimits_{i=1}^{n-1}f_i+n\
    (n-2)f_{n-1}=sumlimits_{i=1}^{n-2}f_i+n-1\
    end{align}\
    (1)-(2),得:\
    (n-1)f_n-(n-2)f_{n-1}=sumlimits_{i=1}^{n-1}f_i+n-(sumlimits_{i=1}^{n-2}f_i+n-1)\
    (n-1)(f_n-f_{n-1})=1\
    f_n-f_{n-1}=dfrac1{n-1}
    $$


    特别的,当$n=2$时,$f_{n-1}$无法用原来的公式来计算,所以$f_n-f_{n-1}$要特别计算,为$2$

    当$n>1$时
    $$
    egin{align*}
    ans&=2+sumlimits_{i=2}^{n-1}dfrac1i\
    &=1+sumlimits_{i=1}^{n-1}dfrac1i
    end{align*}
    $$
    但是$n<2^{31}$,无法$O(n)$计算,但是右边的东西(调和级数$H(x)$)在$n$较大时有一个公式:$H_n=ln(n)+gamma$。($gamma$的定义就是$gamma=limlimits_{n oinfty}H_n-ln(n)$,$gamma=0.57721566490153286060651209008240243104215933593992dots$)

    卡点:

    C++ Code:

    #include <cstdio>
    #include <cmath>
    const int limit = 1000000;
    const long double EulerGamma = 0.577215664901532860606512090082;
    
    int n;
    long double ans = 1;
    int main() {
    	scanf("%d", &n);
    	if (n == 1) {
    		puts("0.00000");
    		return 0;
    	}
    	if (n <= limit) for (int i = 1; i < n; ++i) ans += 1 / static_cast<long double> (i);
    	else ans += logl(n - 1) + EulerGamma;
    	printf("%.5Lf
    ", ans);
    	return 0;
    }
    

      

  • 相关阅读:
    python活力练习Day13
    检测一个字符串在另外一个字符串中的位置
    Python活力练习Day12
    Python多进程与单进程效率对比
    HTML-Note
    Python判断自定义的参数格式是否正确
    图片的灰与彩
    Git常用命令
    Linux 单引号和双引号的区别
    类函数中获取进程池对象的地址
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10354885.html
Copyright © 2011-2022 走看看