牛客15403 wyh的曲线

题目链接

一、题意

给定一个函数,然后求函数对应的曲线的长度。

函数直接看题面吧。

二、题解

弧长积分公式\int_{a}^{b}\sqrt{1+(f^{'}(x))^2}dx

然后套一下自适应辛普森板子就行了,注意迭代加深。

三、代码

#include
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair pii ;
typedef pair pll ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
mt19937  rnd(chrono::high_resolution_clock::now().time_since_epoch().count()) ; 
int n ;
double k[maxn] , a[maxn] , b[maxn] ;
double f(double x) 
{
    double min1 = 100.0 ;
    int temp = 0 ;
    rep(i , 1 , n)
    {
        double y = k[i] * (x - a[i]) * (x - a[i]) + b[i] ;
      if(y < min1)  min1 = y , temp = i ;
    }
    double t = 2 * k[temp] * (x - a[temp]) ;
    return sqrt(1.0 + t * t) ;
}
double simpson(double a , double b)
{
    double c = (a + b) / 2 ;
    return (f(a) + 4 * f(c) + f(b)) * (b - a) / 6 ;   //f(x)是被积分的函数
}
double asr(double a , double b , int dep , double eps , double A)
{
    double c = (a + b) / 2 ;
    double l = simpson(a , c) ;
    double r = simpson(c , b) ;
    if(dep >= 10 && fabs(l + r - A) <= 15 * eps)  return l + r + (l + r - A) / 15.0 ;
    return  asr(a , c , dep + 1 , eps / 2 , l) + asr(c , b , dep + 1 , eps / 2 , r) ;
}
double asr(double l , double r , double eps) 
{
    return asr(l , r , 0 , eps , simpson(l , r)) ;
}
int main()
{
    ios ;
    cin >> n ;
    rep(i , 1 , n)  cin >> k[i] >> a[i] >> b[i] ;
    cout << fixed << setprecision(2) << asr(0 , 100 , 1e-6) << '\n' ;
    return 0 ;
}

 

你可能感兴趣的:(#,数值积分)