Simpson公式:
\[\int^{r}_{l}f(x)dx\approx\frac{(r-l)(f(l)+f(r)+4f(\frac{l+r}{2}))}{6}\]
inline double simpson(double l, double r) { double mid = (l + r) / 2.0; return (r - l) * (f(l) + f(r) + 4.0 * f(mid)) / 6.0; }
自适应Simpson法:
二分枚举精度,就可以了鸭!
以一道洛谷模板题为例LuoGu4525_自适应辛普森法1
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; double a, b, c, d, l, r; inline double f(double x) { return (c * x + d) / (a * x + b); } inline double simpson(double l, double r) { double mid = (l + r) / 2.0; return (r - l) * (f(l) + f(r) + 4.0 * f(mid)) / 6.0; } double asr(double l, double r, double eps, double ans) { double mid = (l + r) / 2; double l_ans = simpson(l, mid), r_ans = simpson(mid, r); if (fabs(l_ans + r_ans - ans) <= eps * 15) return l_ans + r_ans + (l_ans + r_ans - ans) / 15; return asr(l, mid, eps, l_ans) + asr(mid, r, eps, r_ans); } inline double asr(double l, double r, double eps) { return asr(l, r, eps, simpson(l, r)); } int main() { scanf("%lf%lf%lf%lf%lf%lf", &a, &b, &c, &d, &l, &r); printf("%.6lf", asr(l, r, 1e-6)); return 0; }
对于收敛的函数,从1e-8到一个大致收敛成功的数值为止吧
再一道洛谷模板题为例LuoGu4526_自适应辛普森法2
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<ctime> #include<algorithm> using namespace std; double a; inline int read() { int s = 0, w = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') w = -1; for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48); return s * w; } inline double f(double x) { return pow(x, a / x - x); } inline double simpson(double l, double r) { double mid = (l + r) / 2; return (r - l) * (f(l) + f(r) + 4 * f(mid)) / 6; } double asr(double l, double r, double eps, double ans) { double mid = (l + r) / 2; double l_ans = simpson(l, mid), r_ans = simpson(mid, r); if (fabs(l_ans + r_ans - ans) <= eps * 15) return l_ans + r_ans + (l_ans + r_ans - ans) / 15; return asr(l, mid, eps, l_ans) + asr(mid, r, eps, r_ans); } int main() { scanf("%lf", &a); if (a < 0) printf("orz"); else printf("%.5lf", asr(1e-8, 20, 1e-7, simpson(1e-8, 20))); return 0; }