<总结>自适应辛普森积分

不给证明,很好记。
对于一个东西,如果我们能把它假装成一个二次函数,那么我们就把它近似成抛物线求解。
还是看图来得方便

圆锥这个,虽然我们的体积公式是3次方的,但是我们用辛普森积分的话面积f(x)就是二次的了,乘以高,所以还是可以近似成二次函数。

当然我们不能直接套辛普森积分算任何不规则面积,因为误差太大了...比如你试试直接套圆?
那我们就先切分图形?也不行,切小了超时,切大了误差太大。
那么我们什么时候认为辛普森积分算出来的东西是对的呢?
我们把要算的面积分成两块,用辛普森积分算S(0), S(1), S(2),在误差范围内如果S(0)=S(1)+S(2),我们就认为我们算对了。
所以用辛普森积分解题就是一个二分的过程,自己控制切多小。
模板

#include <cstdio>
#include <iostream>
#include <cmath>

inline int dcmp(double x, double eps)
{
    if (x < eps && x > -eps) return 0;
    return x > 0 ? 1 : -1;
}

double a, b, c, d;

inline double f(double x) { return (c * x + d) / (a * x + b); }

inline double sim(double l, double r) { return (f(l) + f(r) + f((l + r) / 2) * 4) / 6 * (r - l); }

inline double solve(double l, double r, double eps)
{
    if (eps != eps)
        eps = 1e-15;
    if (dcmp(sim(l, r) - sim(l, (l+r)/2) - sim((l+r)/2, r), eps) == 0)
        return sim(l, r);
    return solve(l, (l + r) / 2, eps / 2) + solve((l + r) / 2, r, eps / 2);
}

int main(void)
{
    double l, r;
    std::cin >> a >> b >> c >> d >> l >> r;
    std::cout.precision(6);
    std::cout << std::fixed << solve(l, r, 1e-7);
}

这道题题号加1也是模板题,涉及到积分的发散收敛和转化为定积分,所以不说了

然后就是BZOJ2178,可惜是权限题,求圆的面积并。
思路:视作一个大图形,水平切所有的圆所切出来的线段的并的长度为f(x)

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注