zoukankan      html  css  js  c++  java
  • luogu P4525 自适应辛普森法1

    LINK:自适应辛普森法1

    观察题目 这个东西 凭借我们的数学知识应该是化简不了的。

    可以直接认为是一个函数 求定积分直接使用辛普森就行辣.

    一种写法:

    double a,b,c,d;
    double f(double x){
        return (c*x+d)/(a*x+b);
    }
    //区间[a,b]上的辛普森值
    double simpson(double a,double b){
        double c=a+(b-a)/2;
        return (f(a)+4*f(c)+f(b))*(b-a)/6;
    }
    //区间[a,b]上的积分,精度限制为eps,已知整个区间的辛普森值A
    double asr(double a,double b,double eps,double A){
        double c=a+(b-a)/2;
        double L=simpson(a,c),R=simpson(c,b);
        if(fabs(L+R-A)<=15*eps) return L+R+(L+R-A)/15;
        else return asr(a,c,eps/2,L)+asr(c,b,eps/2,R);
    }
    const double eps=1e-7;
    int main(){
        double l,r;
        scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&l,&r);
        printf("%.6f
    ",asr(l,r,eps,simpson(l,r)));
        return 0;
    }
    

    这种 写法比较常见 精度也比较稳 值得注意的是 exp每次需要/2 然后积分的时候要乘上15.

    最后注意 要加上辛普森余项 (L-R-A)/15. (15是人类研究出来的结果 不要问 问就是前沿哥

    一种比较偷懒的写法:

    const int MAXN=1010;
    db a,b,c,d,L,R;
    inline db f(db x){return (c*x+d)/(a*x+b);}
    inline db simpson(db l,db r)
    {
    	db mid=(l+r)/2;
    	return (r-l)*(f(l)+4*f(mid)+f(r))/6;
    }
    inline db jf(db l,db r,db ans)
    {
    	db mid=(l+r)/2;
    	db L=simpson(l,mid),R=simpson(mid,r);
    	if(fabs(L+R-ans)<EPS)return L+R;
    	return jf(l,mid,L)+jf(mid,r,R);
    }
    int main()
    {
    	freopen("1.in","r",stdin);
    	gi(a);gi(b);gi(c);gi(d);gi(L);gi(R);
    	printf("%.6lf",jf(L,R,simpson(L,R)));
    }
    

    EPS开小点直接积分 不过要注意时间 问题 时间不够就开大eps.

  • 相关阅读:
    网络流24题-[CTSC1999]家园
    网络流24题-孤岛营救问题
    汽车加油行驶问题(分层图最短路)
    送外卖(可重复点的哈密顿路径)
    信与信封问题
    最小完全图(最小生成树加边成完全图)
    校园网(有向图加边变成强连通图)
    玩具装箱
    MSTest、NUnit、xUnit对照表
    .NET Core学习 笔记索引
  • 原文地址:https://www.cnblogs.com/chdy/p/12931893.html
Copyright © 2011-2022 走看看