调和级数

调和级数

调和级数:

\[\sum^{\infty}_{k=1} \frac{1}{k} \]

该无穷级数发散。

性质

\[\sum_{k=1}^{n}\frac{1}{k}\approx\log n \]

证明

\(\sum_{k=1}^{n}\frac{1}{k}=1+\frac{1}{2}+\frac{1}{3}+···+\frac{1}{n}\)

\(=(1)+(\frac{1}{2}+\frac{1}{3})+(\frac{1}{4}+\frac{1}{5}+\frac{1}{6}+\frac{1}{7})+···+\frac{1}{n}\)

\(\approx 1+1+1+···+1(约\log n 个1)\)

\(=\log n\).

即将 \(n\) 个数拆成 \(O(\log n)\) 个小区间,每个区间的和趋近为 \(1\)

证毕。

更优秀的估算方法:

\[\sum_{k=1}^{n}\frac{1}{k}\approx \ln n+\gamma+\frac{1}{2n} \]

其中 \(\gamma\) 为欧拉常数,约等于 \(0.577215664901532 860606512090082402431042159335\)

\(n\to \infty\) 时,\(\frac{1}{2n}\) 趋近于 \(0\)。可忽略。

\(n\) 较小时可以暴力 \(O(n)\) 求调和级数值。

较大时就可以用估算法输出 \(\ln n+\gamma\)

例题 1:洛谷p5147 随机数生成器

\(E_i\) 表示函数 \(\operatorname{work}\) 自变量为 \(i\) 时返回值的期望。

那么有:

\[E_n= \begin{cases} 0 & n=1\\ 1+\frac{1}{n}\sum_{k=1}^n E_k &n>1\\ \end{cases} \]

考虑 \(n>1\) 时的情况。

\[\begin{align} &\hspace{0.95cm}E_n=1+\frac{1}{n}\sum_{k=1}^n E_k\notag\\ &=>n\times E_n-E_n-n=\sum_{k=1}^{n-1} E_k\\ \end{align} \]

换元 \(n+1\to n\)

\[\begin{align} n\times E_{n+1}-E_n-n-1=\sum_{k=1}^{n-1} E_k\\ \end{align} \]

联立 \(1\) 式与 \(2\) 式。

\[E_{n+1}-E_{n}=\frac{1}{n} \]

显然,等式左边是一个差分的形式,而右边是一个分子为 \(1\) 的分数。

写出几项就可以发现,\(E_{n}\) 实际上等于 \(\sum_{i=1}^{n-1} \frac{1}{i}\)

求调和级数即可。

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define FOR(i,l,r) for(int i=l;i<=r;++i)
#define ROF(i,r,l) for(int i=r;i>=l;--i)
#define mkp make_pair
#define fr first
#define se second
using namespace std;
const double gama=0.5772156649;
int n;double ans=0;
int main() {
	cin>>n;
	if(n<=10000000) FOR(i,1,n-1) ans+=1.0/i;
	else ans=log(n)+gama;
	if(n==1) ans=-1;
	printf("%.5lf\n",ans+1);
	return 0;
}
posted @ 2024-07-17 01:04  cannotmath  阅读(69)  评论(0编辑  收藏  举报