zoukankan      html  css  js  c++  java
  • [BZOJ 2048] [2009国家集训队]书堆 【调和级数】

    题目链接:BZOJ - 2048

    题目分析

    只有一本书时,这本书的重心落在桌子边缘上,伸出桌面的长度就是 1/2。

    有两本书时,第一本书的重心就落在第二本书的边缘上,两本书的重心落在桌子边缘上,两本书的重心就是在最下面一本书的右端 1/4  处。那么伸出 1/2 + 1/4 。

    三本书时,可以再多伸长 3 本书的重心 1/6 。

    继续计算可以发现规律,i 本书的重心就落在最下面一本书的右端 1/2i 处。

    那么我们要求的伸出的总长度就是 sigma(1 / 2i) = sigma(1 / i) / 2。

    sigma(1 / 2i) 就是调和级数求和,如果 n 比较小,我们就直接 O(n) 求,因为 n 比较小的时候用极限公式求误差会比较大。

    如果 n 很大,我们就用调和级数的极限公式 sigma(1 / i) (i = 1 to n) = ln(n + 1) + r。r 是欧拉常数,r = 0.5772156649015328...

    然后就做完了。

    代码

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    
    typedef double LF;
    typedef long long LL;
    
    #define r 0.5772156649
    
    const LF Eps = 1e-10;
    
    LL n, m;
    
    LF Ans;
    
    int main()
    {
    	scanf("%lld%lld", &n, &m);
    	if (n <= 1000000ll)
    	{	
    		for (int i = 1; i <= n; ++i)
    			Ans += 1.0 / (LF)i;
    	}
    	else Ans = log((LF)(n + 1)) + r;
    	Ans /= 2.0; Ans *= (LF)m;
    	printf("%d
    ", (int)(Ans - Eps));
    	return 0;
    }
    

      

  • 相关阅读:
    android的HTTP框架之Volley
    android学习笔记五。2、其他组件
    android学习笔记四
    android学习笔记二、Activity深入学习
    android事件学习
    android之handler机制深入解析
    java线程深入学习
    K-Means
    git fetch + merge与 git pull的区别
    git分支管理
  • 原文地址:https://www.cnblogs.com/JoeFan/p/4566110.html
Copyright © 2011-2022 走看看