• Simpson&自适应Simpson


    Simpson公式:

    [int^{r}_{l}f(x)dxapproxfrac{(r-l)(f(l)+f(r)+4f(frac{l+r}{2}))}{6} ]

    inline double simpson(double l, double r) {
    	double mid = (l + r) / 2.0;
    	return (r - l) * (f(l) + f(r) + 4.0 * f(mid)) / 6.0;
    }
    

    自适应Simpson法:
    二分枚举精度,就可以了鸭!
    以一道洛谷模板题为例LuoGu4525_自适应辛普森法1

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    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 mid = (l + r) / 2.0;
    	return (r - l) * (f(l) + f(r) + 4.0 * f(mid)) / 6.0;
    }
    double asr(double l, double r, double eps, double ans) {
    	double mid = (l + r) / 2;
    	double l_ans = simpson(l, mid), r_ans = simpson(mid, r);
    	if (fabs(l_ans + r_ans - ans) <= eps * 15) return l_ans + r_ans + (l_ans + r_ans - ans) / 15;
    	return asr(l, mid, eps, l_ans) + asr(mid, r, eps, r_ans);
    }
    inline double asr(double l, double r, double eps) {
    	return asr(l, r, eps, simpson(l, r));
    }
    int main() {
    	scanf("%lf%lf%lf%lf%lf%lf", &a, &b, &c, &d, &l, &r);
    	printf("%.6lf", asr(l, r, 1e-6));
    	return 0;
    }
    
    

    对于收敛的函数,从1e-8到一个大致收敛成功的数值为止吧
    再一道洛谷模板题为例LuoGu4526_自适应辛普森法2

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    #include<algorithm>
    using namespace std;
    double a;
    inline int read() {
    	int s = 0, w = 1;
    	char c = getchar();
    	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
    	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
    	return s * w;
    }
    inline double f(double x) {
    	return pow(x, a / x - x);
    }
    inline double simpson(double l, double r) {
    	double mid = (l + r) / 2;
    	return (r - l) * (f(l) + f(r) + 4 * f(mid)) / 6;
    }
    double asr(double l, double r, double eps, double ans) {
    	double mid = (l + r) / 2;
    	double l_ans = simpson(l, mid), r_ans = simpson(mid, r);
    	if (fabs(l_ans + r_ans - ans) <= eps * 15) return l_ans + r_ans + (l_ans + r_ans - ans) / 15;
    	return asr(l, mid, eps, l_ans) + asr(mid, r, eps, r_ans);
    }
    int main() {
    	scanf("%lf", &a);
    	if (a < 0) printf("orz");
    	else printf("%.5lf", asr(1e-8, 20, 1e-7, simpson(1e-8, 20)));
    	return 0;
    }
    
    只要有想见的人,就不是孤身一人了。
  • 相关阅读:
    Linux学习 -- Shell编程 -- 字符截取命令
    Linux学习 -- Shell编程 -- 正则表达式
    Linux学习 -- Shell基础 -- Bash变量
    Linux学习 -- Shell基础 -- Bash基本功能
    Linux学习 -- Shell基础 -- 概述
    Linux学习 -- 备份与恢复
    Linux学习 -- 启动管理
    Linux学习 -- 日志管理
    chapter9_3 协同程序实现迭代器
    chapter9_2 管道与过滤器
  • 原文地址:https://www.cnblogs.com/Agakiss/p/11568853.html
Copyright © 2020-2023  润新知