oval-and-rectangle

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5507    Accepted Submission(s): 872


Problem Description

Patrick Star find an oval.


The half of longer axes is on the x-axis with length a.


The half of shorter axes is on the y-axis with length b.


Patrick Star plan to choose a real number c randomly from [0,b], after that, Patrick Star will get a rectangle :


1. The four vertexes of it are on the outline of the oval.


2. The two sides of it parallel to coordinate axis.


3. One of its side is y=c.


Patrick Star want to know the expectations of the rectangle's perimeter.


Input

The first line contain a integer T (no morn than 10), the following is T test case, for each test case :


Each line contains contains two integer a, b (0<b<a<105). Separated by an white space.


Output

For each test case output one line denotes the expectations of the rectangle's perimeter .


You should keep exactly 6 decimal digits and ignore the remain decimal digits. 


It is guaranted that the 7-th decimal digit of answer wont be 0 or 9.


Sample Input

1

2 1


Sample Output

8.283185

题目大意:求所有满足至少一条边长度==[0,b]范围内的椭圆内接矩形的周长期望值。

解题思路:自适应辛普森积分公式:定积分可以拿来求面积也可以求长度。

推到 double f() 内部公式:
由椭圆公式:HDU - 2018 Multi-University Training Contest 6 - 1001: oval-and-rectangle_HDU (1)

由构造函数:F(y)=4(x+y) (2)// 四条边的长度之和

把 x 表达式代入 y 得:F(y) == a*sqrt(1-(y*y)/(b*b))+y。

Ps1:“ignore the remain decimal digits”:禁止四舍五入。

Ps2:“guaranted that the 7-th decimal digit of answer wont be 0 or 9”:因为题目是保留6位小数,第7位如果是 0 or 9,可能会发生精度丢失,比如:1.10 ~ 1.099999999。

Ps3:最后“4*integral(0,b,eps)/b” 是针对期望值,因为枚举 x=[0,b] 开始,期望公式的概率可以看成它们是相互独立的,使得概率也一样(哪怕它们值一样也无视,只要把它们想成是相互独立的就行,它们的概率就是一样的)。

AC 代码

#include<bits/stdc++.h>
#include<cmath>

#define mem(a,b) memset(a,b,sizeof a);
#define INF 0x3f3f3f3f
#define MOD 1000000007

using namespace std;

typedef long long ll;

double a,b;

double f(double y)
{
return a*sqrt(1-(y*y)/(b*b))+y;
}

double simpson(double a,double b)
{
double mid=a+(b-a)/2;
return (f(a)+4*f(mid)+f(b))*(b-a)/6;
}

double integral(double l,double r,double eps)
{
double mid=l+(r-l)/2;
double ST=simpson(l,r), SL=simpson(l,mid), SR=simpson(mid,r);
if(fabs(SL+SR-ST)<=15*eps) return SL+SR+(SL+SR-ST)/15;
return integral(l,mid,eps/2)+integral(mid,r,eps/2);
}

int main()
{
int T; scanf("%d",&T);
while(T-- && ~scanf("%lf%lf",&a,&b))
{
double eps=1e-7;
printf("%.6f\n",ll(4*integral(0,b,eps)/b*1000000)/1000000.0);
}

return 0;
}