zoukankan      html  css  js  c++  java
  • Luogu4525【模板】自适应辛普森法1

    Luogu4525【模板】自适应辛普森法1

    题面:洛谷

    解析

    讲一讲这东西吧。

    自适应辛普森法的原理就是用二次函数来拟合所给函数,然后计算二次函数的积分得到近似答案,这里首先给出二次函数的积分公式(也就是所谓的辛普森公式)并证明。

    [=int_{l}^{r} F(x){ m d}x ]

    [=int_{l}^{r} (ax^2+bx+c){ m d}x ]

    [=frac{a}{3}r^3+frac{b}{2}r^2+cr-frac{a}{3}l^3-frac{b}{2}l^2-cl ]

    [=frac{2 imes ar^3 +3 imes br^2 +6r-2 imes al^3 -3 imes bl^2 -6l}{6} ]

    [=(r-l)frac{2a(r^2+rl+l^2)+3b(r+l)+6c}{6} ]

    [=(r-l)frac{ar^2+br+c+al^2+bl+c+4a(frac{r+l}{2})^2+4bfrac{r+l}{2}+4c}{6} ]

    [=(r-l)frac{F(l)+F(r)+4F(mid)}{6} ]

    然后它的思想是尽量用这个公式去计算积分,但是由于精度,所以要分段计算,容易计算的少分段,难以计算的多分段。如何判断呢?分别计算左右两部的积分加起来与当前积分比较就行了,具体实现请看代码。

    代码

    
    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    using namespace std;
    const double eps=1e-7;
    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 a=F(l),b=F(r),c=F((l+r)/2.0);
        return (r-l)*(a+b+4*c)/6.0;
    }
    inline double asr(double l,double r,double A){
        double mid=(l+r)/2.0,L=simpson(l,mid),R=simpson(mid,r);
        if(fabs(L+R-A)<=15*eps) return L+R+(L+R-A)/15.0;
        else return asr(l,mid,L)+asr(mid,r,R);
    }
    inline double asr(double L,double R){ return asr(L,R,simpson(L,R)); }
    int main(){
        scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&L,&R);
        printf("%.6lf
    ",asr(L,R));
        return 0;
    }
    
    
    
  • 相关阅读:
    java8接口新特性
    美团后台开发面试经验
    美团后台开发面试经验
    HashMap源码阅读之get/put/resize方法
    腾讯系统测试面试经验
    携程实习生春招面经-后台开发
    Python-if else流程判断
    python中信息拼接打印
    数据库查询-关于exists的使用
    关于网站防护的建议
  • 原文地址:https://www.cnblogs.com/pkh68/p/10539841.html
Copyright © 2011-2022 走看看