洛谷 P12037 题解
传送门:[P12037 [USTCPC 2025] 数学分析](https://www.luogu.com.cn/problem/P12037)
更佳的阅读体验:洛谷 P12037 题解
在阅读本题解之前,请确保你已经对定积分有所了解。
简要题意:给定多项式 $P(x) = a_0 + a_1 x + a_2 x^2 + \cdots a_n x^n$,求 $\displaystyle \int_0^1 \dfrac{P(x)}{x^2 + 1} dx$ 的值。
我们令积分的值为 $I$,则有:
$$ I = \int_0^1 \dfrac{\sum \limits_{k = 0}^n a_k x^k}{x^2 + 1} dx = \int_0^1 \sum \limits_{k = 0}^{n} \dfrac{a_k x^k}{x^2 + 1} $$
我们知道,定积分有加法法则:
$$ \int_a^b [f(x) + g(x)] dx = \int_a^b f(x) dx + \int_a^b g(x) dx $$
因此,我们可以将积分拆解为:
$$ I = \sum \limits_{k = 0}^{n} \int_0^1 \dfrac{a_k x^k}{x^2 + 1} dx $$
又因为 $a_i$ 是给定常数,所以我们可以将 $a_i$ 提出来,得到:
$$ I = \sum \limits_{k = 0}^{n} a_k \int_0^1 \dfrac{x^k}{x^2 + 1} dx = \sum \limits_{k = 0}^{n} a_k I_k $$
其中 $I_k = \displaystyle \int_0^1 \dfrac{x^k}{x^2 + 1} dx$。此时,问题转化为如何计算 $I_k$。
当 $k = 0$ 时,积分简化为标准积分,有:
$$ I_0 = \int_0^1 \dfrac{1}{x^2 + 1} dx = \arctan(x) \Big|_0^1 = \dfrac{\pi}{4} $$
当 $k = 1$ 时,有:
$$ I_1 = \int_0^1 \dfrac{x}{x^2 + 1} dx = \dfrac{1}{2} \ln (x^2 + 1) \Big|_0^1 = \dfrac{\ln 2}{2} $$
对于 $k \ge 2$,我们需要找到 $I_k$ 与 $I_{k - 2}$ 之间的关系。我们将分子 $x^k$ 拆成 $x^{k - 2} \cdot x^2$,并利用恒等式 $x^2 = (x^2 + 1) - 1$,则有:
$$ \begin{align*} I_k & = \int_0^1 \dfrac{x^k}{x^2 + 1} dx \\ & = \int_0^1 \dfrac{x^{k - 2} \cdot x^2}{x^2 + 1} dx \\ & = \int_0^1 x^{k - 2} \cdot \dfrac{x^2}{x^2 + 1} dx \\ & = \int_0^1 x^{k - 2} \cdot \dfrac{(x^2 + 1) - 1}{x^2 + 1} dx \\ & = \int_0^1 x^{k - 2} \cdot \left ( 1 - \dfrac{1}{x^2 + 1} \right ) dx \\ & = \int_0^1 \left ( x^{k - 2} - \dfrac{x^{k - 2}}{x^2 + 1} \right ) dx \\ & = \int_0^1 x^{k - 2} dx - \int_0^1 \dfrac{x^{k - 2}}{x^2 + 1} dx \\ \end{align*} $$
此时发现,第一项已经可以直接求出积分的值了,第二项其实就是 $I_{k - 2}$,因此我们得到了递推式:
$$ I_k = \dfrac{1}{k - 1} - I_{k - 2} $$
问题也就迎刃而解了。
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
const int N = 1e5 + 10;
int n, a[N];
double i[N], ans;
int main() {
cin >> n;
for (int k = 0; k <= n; ++k) cin >> a[k];
i[0] = M_PI / 4.0, i[1] = 0.5 * log(2);
for (int k = 2; k <= n; ++k) i[k] = 1.0 / (k - 1) - i[k - 2];
for (int k = 0; k <= n; ++k) ans += a[k] * i[k];
cout << setprecision(10) << ans << '\n';
return 0;
}