跳到主要内容

积分

参考资料

自适应辛普森法

#include <bits/stdc++.h>
#define mid ((l+r)/2)
using namespace std;

const double eps=1e-8;
double a;
double F(double x)
{
return pow(x,a/x-x);
}
double simp(double l,double r)
{
return (F(l)+F(r)+F(mid)*4)*(r-l)/6;
}
double asr(double l,double r,double e,double ans)
{
double L=simp(l,mid),R=simp(mid,r);
if(fabs(L+R-ans)<=e*15)return L+R+(L+R-ans)/15;
return asr(l,mid,e/2,L)+asr(mid,r,e/2,R);
}
double calc(double l,double r,double e)
{
return asr(l,r,e,simp(l,r));
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>a;
if(a<0)cout<<"orz"<<'\n';
else cout<<fixed<<setprecision(5)<<calc(eps,20,eps)<<'\n';
return 0;
}

例题

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

给定实数 aa,计算积分 0xaxxdx\displaystyle{\int_0^\infty x^{\frac{a}{x}-x}\mathrm{d}x}。若积分发散,请输出 orz。(a50|a|\le 50

#include <bits/stdc++.h>
#define mid ((l+r)/2)
using namespace std;

const double eps=1e-8;
double a;
double F(double x)
{
return pow(x,a/x-x);
}
double simp(double l,double r)
{
return (F(l)+F(r)+F(mid)*4)*(r-l)/6;
}
double asr(double l,double r,double e,double ans)
{
double L=simp(l,mid),R=simp(mid,r);
if(fabs(L+R-ans)<=e*15)return L+R+(L+R-ans)/15;
return asr(l,mid,e/2,L)+asr(mid,r,e/2,R);
}
double calc(double l,double r,double e)
{
return asr(l,r,e,simp(l,r));
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin>>a;
if(a<0)cout<<"orz"<<'\n';
else cout<<fixed<<setprecision(5)<<calc(eps,20,eps)<<'\n';
return 0;
}