【洛谷 P4525】 【模板】自适应辛普森法 1
自适应辛普森法,用于求定积分。
原理是不断二分区间直到区间的积分和二次函数的积分拟合程度足够高,然后用二次函数的积分值来代替原积分值。
#include <bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define pb push_back
#define rep(i, m, n) for(int i = (m); i <= (n); ++i)
#define dop(i, m, n) for(int i = (m); i >= (n); --i)
#define all(x) x.begin(), x.end()
#define Open(s) freopen(s,"r",stdin);
#define Write(s) freopen(s,"w",stdout);
using namespace std;
typedef long long ll;
template <class T> void chkmin(T &a, T b){ if(a > b) a = b; }
template <class T> void chkmax(T &a, T b){ if(a < b) a = b; }
template <class T> T aabs(T a){ return a > 0 ? a : -a; }
const int N = 200010;
double a, b, c, d, L, R;
double f(double x){
return (c*x + d) / (a*x + b);
}
double simpson(double l, double r){
double mid = (l + r) / 2;
return (r - l) * (f(l) + 4 * f(mid) + f(r)) / 6;
}
double asr(double l, double r, double eps, double ans){
double mid = (l + r) / 2;
double fl = simpson(l, mid), fr = simpson(mid, r);
if(fabs(fl + fr - ans) <= 15 * eps) return fl + fr + (fl + fr - ans) / 15;
return asr(l, mid, eps/2, fl) + asr(mid, r, eps/2, fr);
}
int main(){
cin >> a >> b >> c >> d >> L >> R;
cout << setprecision(6) << fixed << asr(L, R, 1e-6, simpson(L, R)) << endl;
return 0;
}