浅谈圆的面积并(自适应辛普森)
首先考虑对一个函数积分
∫
a
b
f
(
x
)
d
x
\int _ a ^ b \mathrm f(x) \,\mathrm { d } x
∫abf(x)dx
如果这个函数可以用一个二次函数来拟合,则可以写成
≈
∫
a
b
A
x
2
+
B
x
+
C
=
A
3
(
b
3
−
a
3
)
+
B
2
(
b
2
−
a
2
)
+
C
(
b
−
a
)
=
b
−
a
6
(
2
A
(
a
2
+
a
b
+
b
2
)
+
3
B
(
a
+
b
)
+
6
C
)
=
b
−
a
6
(
2
A
a
2
+
2
A
a
b
+
2
A
b
2
+
3
B
a
+
3
B
b
+
6
C
)
=
b
−
a
6
(
f
(
a
)
+
f
(
b
)
+
4
f
(
a
+
b
2
)
)
\approx \int_a^bAx^2+Bx+C \\ = \frac{A}{3}(b^3-a^3)+\frac{B}{2}(b^2-a^2)+C(b-a) \\ = \frac{b-a}{6}(2A(a^2+ab+b^2)+3B(a+b)+6C) \\ = \frac{b-a}{6}(2Aa^2+2Aab+2Ab^2+3Ba+3Bb+6C) \\ = \frac{b-a}{6}(f(a)+f(b)+4f(\frac{a+b}{2}))
≈∫abAx2+Bx+C=3A(b3−a3)+2B(b2−a2)+C(b−a)=6b−a(2A(a2+ab+b2)+3B(a+b)+6C)=6b−a(2Aa2+2Aab+2Ab2+3Ba+3Bb+6C)=6b−a(f(a)+f(b)+4f(2a+b))
于是乎就得到了这个函数的拟合公式,即Simpson积分
∫
a
b
f
(
x
)
d
x
≈
(
b
−
a
)
(
f
(
a
)
+
f
(
b
)
+
4
f
(
a
+
b
2
)
)
6
\int _ a ^ b \mathrm f(x) \,\mathrm { d } x \approx \frac{(b-a)(f(a)+f(b)+4f(\frac{a+b}{2}))}{6}
∫abf(x)dx≈6(b−a)(f(a)+f(b)+4f(2a+b))
考虑怎么取逼近,每次取一个中点,左右两边分别拟合,如果加起来的结果和直接拟合的结果相差不大,那么说明不用继续分段拟合下去了
其实就是分段拟合,如果当前段的拟合值和分成两端的拟合值加起来相差比较大就继续分段下去,分的段越多,拟合的越准确
然后冲板子就是了
luogu P4525 【模板】自适应辛普森法1
#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-11;
double a, b, c, d;
double f(double x) {
return (c * x + d) / (a * x + b);
}
double simpson(double l, double r) {
return (r - l) * (f(l) + f(r) + 4 * f((r + l) / 2)) / 6;
}
double ASR(double l, double r, double ans) {
double mid = (l + r) / 2;
double L = simpson(l, mid), R = simpson(mid, r);
if(fabs(L + R - ans) < eps) return L + R;
return ASR(l, mid, L) + ASR(mid, r, R);
}
double L, R;
int main() {
scanf("%lf%lf%lf%lf%lf%lf", &a, &b, &c, &d, &L, &R);
printf("%.6f", ASR(L, R, simpson(L, R)));
return 0;
}