自适应辛普森法


定积分

自适应辛普森法 $1$

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

  • 备注:

因为($C$ 是常数):

同样:

上面的定积分连接中有详细讲解(或者定积分的链接中)。

代码

套公式即可。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<vector>
#include<random>
#include<ctime>
using namespace std;
long long r_r(){//快读 
  long long k=0,f=1;
  char c=getchar();
  while(!isdigit(c)){
    if(c=='-')f=-1;
    c=getchar();
  }
  while(isdigit(c)){
    k=(k<<1)+(k<<3)+(c^48);
    c=getchar();
  }
  return k*f;
}
double a,b,c,d,l,r;
double f(double x){
  return (c*x+d)/(a*x+b);
}
double s_p(double l,double r){
  double m_i=(l+r)/2;
  return (f(l)+4*f(m_i)+f(r))*(r-l)/6;
}
double g_a(double l,double r,double m_n,double a_s){
  double m_i=(l+r)/2;
  double n_l=s_p(l,m_i);
  double n_r=s_p(m_i,r);
  if(fabs(n_l+n_r-a_s)<=15*m_n)return n_l+n_r+(n_l+n_r-a_s)/15;
  return g_a(l,m_i,m_n/2,n_l)+g_a(m_i,r,m_n/2,n_r);
}
int main() {
  scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&l,&r);
  printf("%.6lf",g_a(l,r,1e-6,s_p(l,r)));
  return 0;
}

自适应辛普森法 2

P4526 【模板】自适应辛普森法 2

  • $a < 0$ 发散

  • $a\ge 0$ 收敛

将区段(可以找右端点值,右端点之后的贡献在精度承受范围内)不断缩小(二分),误差在精度承受范围内,套用自适应辛普森法 $1$ 的公式累计结果即可。

扩展一个公式(解释代码中 $15$ 的来源):

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<vector>
#include<random>
#include<ctime>
using namespace std;
long long r_r(){//快读 
  long long k=0,f=1;
  char c=getchar();
  while(!isdigit(c)){
    if(c=='-')f=-1;
    c=getchar();
  }
  while(isdigit(c)){
    k=(k<<1)+(k<<3)+(c^48);
    c=getchar();
  }
  return k*f;
}
const double m_n=1e-10;
double a,l,r;
double f(double x){
    return pow(x,(a/x)-x);
}
double s_p(double p,double q){
    double k=p+(q-p)/2;
    return (f(p)+4*f(k)+f(q))*(q-p)/6.0;
}
double f_s(double p,double q,double k){
    double k=p+(q-p)/2;
    double l_l=s_p(p,k);
  double r_r=s_p(k,q);
    if(fabs(l_l+r_r-k)<=15*m_n)return l_l+r_r;
    else return f_s(p,k,l_l)+f_s(k,q,r_r);
}
int main(){
    scanf("%lf",&a);
    if(a<0){
        printf("orz");
        return 0;
    }
    printf("%.5lf",f_s(m_n,15,s_p(l,r)));
    return 0; 
}

文章作者: 王大神——A001
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 王大神——A001 !
  目录