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;
    }
    

      

  • 相关阅读:
    WC2020「Illusory」
    WC2015-2019
    Java基础——数组
    Java基础——Java基础语法和使用
    完善README——MarkDown模板[EN]
    完善README——MarkDown模板[CN]
    完善README——Markdown语法概要总结
    Java基础——Java如何导入本地项目
    Java基础——Java的历史以及平台应用
    AndroidSDK——和风天气使用初体验
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10354885.html
Copyright © 2011-2022 走看看