二次函数的定积分
对于一个二次函数 ,显然有
对于一个奇怪的函数,为了对其求导,我们可以用一个图像近似且容易求导的函数(这里我们使用二次函数)来代替它(拟合),这样的话精度误差可能会很大,因此我们需要将函数分段拟合。
自适应辛普森法
显然我们并不知道分成多少段合适,因为段分得越多,精度误差越小,但时间消耗越大;段分得越少,精度误差越大,但时间消耗越小。
我们需要一个“自适应”的操作。
如果这一段函数与拟合的二次函数“相似”,那么我们直接把这一段当做这个二次函数,然后套用公式计算;如果这一段函数与拟合的二次函数“不相似”,那么我们应该把这一段分成两半,并递归进行这一过程。
接下来的问题就是,如何判断是否“相似”呢?
我们可以对整段、左半部分、右半部分分别套用二次函数定积分公式进行计算,结果分别记作 ans、lans 和 rans,若 lans + rans 与 ans 相差的值不超过我们设定的精度了,那么我们就认为这一段函数与拟合的二次函数是“相似”的。
#include<bits/stdc++.h> // https://www.luogu.com.cn/problem/P4525 using namespace std; const double eps = 1e-6; double a, b, c, d, L, R; double f(double x) { return (c * x + d) / (a * x + b); } double simpson(double l, double r) { double mid = (l + r) / 2; return (f(l) + f(r) + 4 * f(mid)) * (r - l) / 6; } double asr(double l, double r, double ep, double ans) { double mid = (l + r) / 2; double lans = simpson(l, mid); double rans = simpson(mid, r); if (fabs(lans + rans - ans) <= 15 * ep) return lans + rans + (lans + rans - ans) / 15; return asr(l, mid, ep/2, lans) + asr(mid, r, ep/2, rans); } int main() { scanf("%lf%lf%lf%lf%lf%lf", &a, &b, &c, &d, &L, &R); printf("%.6f\n", asr(L, R, eps, simpson(L, R))); return 0; }
常数优化
#include<bits/stdc++.h> //https://www.luogu.com.cn/problem/P4526 using namespace std; const double eps = 1e-8; double a; double f(double x) { return pow(x, a/x-x); } double simpson(double len, double fl, double fr, double fm) { return (fl + fr + 4 * fm) * len / 6; } double asr(double l, double r, double ep, double fl, double fr, double fm) { double len = r - l; double flm = f(l+len/4); double frm = f(r-len/4); double ans = simpson(len, fl, fr, fm); double lans = simpson(len/2, fl, fm, flm); double rans = simpson(len/2, fm, fr, frm); if (fabs(lans + rans - ans) <= 15 * ep) return lans + rans + (lans + rans - ans) / 15; return asr(l, l+len/2, ep/2, fl, fm, flm) + asr(l+len/2, r, ep/2, fm, fr, frm); } int main() { scanf("%lf", &a); if (a < 0) printf("orz\n"); else printf("%.5f\n", asr(eps, 15, eps, f(eps), f(15), f((eps+15)/2))); return 0; }
应用
求定积分
https://www.luogu.com.cn/problem/P4525 【第一类曲面积分】
https://www.luogu.com.cn/problem/P4526 【反常积分】