• 洛谷4525 & 4526:【模板】自适应辛普森法——题解


    参考:https://phqghume.github.io/2018/05/19/%E8%87%AA%E9%80%82%E5%BA%94%E8%BE%9B%E6%99%AE%E6%A3%AE%E6%B3%95/ 以及洛谷不多的题解。

    辛普森推导过程就看参考吧,当然你要想看懂推导需要:

    1.会高中导数那点东西,至少知道原函数怎么求。

    2.粗略了解定积分。

    3.知道微积分第一、第二基本定理(从知乎上找的:https://www.zhihu.com/question/21439225)

    然后推导就很简单了,实际上就是用的是将任意曲线近似转换成二次函数曲线去求。

    ————————————————————

    https://www.luogu.org/problemnew/show/P4525

    计算积分

    结果保留至小数点后6位。

    数据保证计算过程中分母不为0且积分能够收敛。

    这就是自适应辛普森的板题了,eps开到1e-12大概就能过了。

    (话说为什么要“自适应”?那当然是因为精度的原因啦,我们左右分一下将答案求和和一个区间的答案比较一下没有多少误差就return就行啦。)

    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef double dl;
    const dl eps=1e-12;
    dl a,b,c,d,L,R;
    inline dl f(dl x){
        return (c*x+d)/(a*x+b);
    }
    inline dl simpson(dl l,dl r){
        dl mid=(l+r)/2;
        return (f(l)+4*f(mid)+f(r))*(r-l)/6;
    }
    inline dl asr(dl l,dl r,dl ans){
        dl mid=(l+r)/2;
        dl l1=simpson(l,mid),r1=simpson(mid,r);
        if(fabs(l1+r1-ans)<eps)return l1+r1;
        return asr(l,mid,l1)+asr(mid,r,r1);
    }
    int main(){
        scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&L,&R);
        printf("%lf
    ",asr(L,R,simpson(L,R)));
        return 0;
    }

    ————————————————————

    https://www.luogu.org/problemnew/show/P4526

    计算积分

    保留至小数点后5位。若积分发散,请输出"orz"。

    挺吓人的,但思考a<0显然就发散了。

    a>=0时a越大收敛得越慢,于是打表,大概得出来x=12时就已经约为0了。

    于是L=eps,R=12跑一遍自适应辛普森法即可。

    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef double dl;
    const dl eps=1e-12;
    dl a;
    inline dl f(dl x){
        return pow(x,a/x-x);
    }
    inline dl simpson(dl l,dl r){
        dl mid=(l+r)/2;
        return (f(l)+4*f(mid)+f(r))*(r-l)/6;
    }
    inline dl asr(dl l,dl r,dl ans){
        dl mid=(l+r)/2;
        dl l1=simpson(l,mid),r1=simpson(mid,r);
        if(fabs(l1+r1-ans)<eps)return l1+r1;
        return asr(l,mid,l1)+asr(mid,r,r1);
    }
    int main(){
        scanf("%lf",&a);
        if(a<0)puts("orz");
        else printf("%.5lf
    ",asr(eps,12,simpson(eps,12)));
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    ncover
    bash
    .net framework 工具
    keePass
    jersey
    i-jetty
    如何查看set环境变量的更改
    C语言丨如果你不是程序员,绝对看不懂这三个符号!(= 和==、!=)
    忘记 root 密码怎么办?教你4种使用MySQL方式修改密码!(超实用)
    一线城市容不下肉体,二三线城市安放不了灵魂,程序员何处为家?
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/9068106.html
Copyright © 2020-2023  润新知