Problem:
Problem E:
Psychic Accelerator
In the west of Tokyo, there is a city named “Academy City.” There are many schools and laboratories to develop psychics in Academy City.
You are a psychic student of a school in Academy City. Your psychic ability is to give acceleration to a certain object.
You can use your psychic ability anytime and anywhere, but there are constraints. If the object remains stationary, you can give acceleration to the object in any direction. If the object is moving, you can give acceleration to the object only in 1) the direction the object is moving to, 2) the direction opposite to it, or 3) the direction perpendicular to it.
Today’s training menu is to move the object along a given course. For simplicity you can regard the course as consisting of line segments and circular arcs in a 2-dimensional space. The course has no branching. All segments and arcs are connected smoothly, i.e. there are no sharp corners.
In the beginning, the object is placed at the starting point of the first line segment. You have to move the object to the ending point of the last line segment along the course and stop the object at that point by controlling its acceleration properly. Before the training, a coach ordered you to simulate the minimum time to move the object from the starting point to the ending point.
Your task is to write a program which reads the shape of the course and the maximum acceleration
a
max
you can give to the object and calculates the minimum time to move the object from the starting point to the ending point.
The object follows basic physical laws. When the object is moving straight in some direction, with acceleration either forward or backward, the following equations hold:
v
=
v
0
+
at
and
s
=
v
0
t
+ (1/2)
at
2
where
v
,
s
,
v
0
,
a
, and
t
are the velocity, the distance from the starting point, the initial velocity (i.e. the velocity at the starting point), the acceleration, and the time the object has been moving in that direction, respectively. Note that they can be simplified as follows:
v
2
−
v
0
2
= 2
as
When the object is moving along an arc, with acceleration to the centroid, the following equations hold:
a
=
v
2
/
r
wher
v
,
a
, and
r
are the velocity, the acceleration, and the radius of the arc, respectively. Note that the object cannot change the velocity due to the criteria on your psychic ability.
Input
The input has the following format:
N a
max
x
a
,1
y
a
,1
x
b
,1
y
b
,1
x
a
,2
y
a
,2
x
b
,2
y
b
,2
.
.
.
N
is the number of line segments;
a
max
is the maximum acceleration you can give to the object; (
x
a,i
,
y
a,i
) and (
x
b,i
,
y
b,i
) are the starting point and the ending point of the
i
-th line segment, respectively. The given course may have crosses but you cannot change the direction there.
The input meets the following constraints: 0 <
N
≤ 40000, 1 ≤
a
max
≤ 100, and -100 ≤
x
a
i
,
y
a
i
,
x
b
i
,
y
b
i
≤ 100.
Output
Print the minimum time to move the object from the starting point to the ending poi
...(truncated)

Submitted solutions:

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <algorithm>
#include <iostream>
#include <string>
#include <set>
#define X first
#define Y second
#define sqr(x) (x)*(x)
using namespace std;
const double PI = acos(-1.0);
map<int,int>::iterator it;
typedef long long LL ;
#pragma comment(linker,"/STACK:102400000,102400000")
double eps=1e-7;
struct point
{
    double x,y;
};
const int N = 40004;
struct Segment
{
    point st,ed;
    point vec;
    double mxs,mxe;
    double len,A,B,C;
    void pre()
    {
        A = st.y - ed.y;
        B = ed.x - st.x;
        C =  (st.x-ed.x)*st.y-(st.y-ed.y)*st.x;
        vec.x=ed.x-st.x;
        vec.y=ed.y-st.y;
        len = sqrt(sqr(vec.x)+sqr(vec.y) );
    }
    point cross(Segment l)
    {
        point ret ;
        double A1=A, B1=B, C1=C;
        double A2=l.A, B2=l.B, C2=l.C;
        //printf("A1=%f,B1=%f,C1=%f\n",A1,B1,C1);
        //printf("A2=%f,B2=%f,C2=%f\n",A2,B2,C2);
        ret.x=(B1*C2-B2*C1)/(A1*B2-A2*B1);
        ret.y=(A1*C2-A2*C1)/(A2*B1-A1*B2);
        return ret;
    }
} S[N];
int n;
double a;

bool parr(Segment a,Segment b)
{
    return fabs( (a.st.x-a.ed.x)*(b.st.y-b.ed.y) - (a.st.y-a.ed.y)*(b.st.x-b.ed.x)  )<eps;
}
double dot(Segment a,Segment b)
{
    return a.vec.x*b.vec.x+a.vec.y*b.vec.y;
}
double get_m(Segment a)
{
    return sqrt(sqr(a.vec.x)+sqr(a.vec.y) );
}
double get_cos(Segment a,Segment b)
{
    return dot(a,b)/get_m(a)/get_m(b);
}
double get_dis(point a,point b)
{
    return sqrt( sqr(a.x-b.x) + sqr(a.y-b.y) );
}
double get_r(Segment a,Segment b)
{
    if(fabs(fabs(get_cos(a,b))-1)<eps)
    {
        return get_dis(a.ed,b.st)/2.0;
    }
    point p,q;
    p.x = a.ed.x + b.vec.x;
    p.y = a.ed.y + b.vec.y;
    q.x = b.st.x + a.vec.x;
    q.y = b.st.y + a.vec.y;
    Segment pp,qq ;
    pp.st = p;
    pp.ed = a.ed;
    qq.st = q;
    qq.ed = b.st;
    pp.pre();
    qq.pre();
    //printf("p=%f,%f\n",p.x,p.y);
    //printf("q=%f,%f\n",q.x,q.y);
    point ret = pp.cross(qq);
    //printf("segment %f,%f -> %f,%f\n and %f,%f -> %f,%f\n",a.st.x,a.st.y,a.ed.x,a.ed.y,b.st.x,b.st.y,b.ed.x,b.ed.y);
    //printf("cross at %f,%f\n",ret.x,ret.y);
    return get_dis(ret,a.ed);
}
double res;

void gao(double mxs,double mxe,double len,double v0,double &v1,double &t)
{
    double S1,S2,t1,t2;
    v1=0,t=0;
    //printf("%f %f %f %f %f %f\n",mxs,mxe,len,v0,v1,t);
    if( sqrt( sqr(v0) + 2.0*a*len ) > mxe )
    {
        v1 = mxe;
    }
    else
    {
        v1 = sqrt( sqr(v0) + 2*a*len );
    }
    //printf("v0 = %f v1 = %f a = %f\n",v0,v1,a);
    S1 = len/2 + ((sqr(v1)-sqr(v0))/a/4);
    //printf("%.6f %.6f %.6f %.6f\n",S1,S2,t1,t2);
    S2 = len/2 - ((sqr(v1)-sqr(v0))/a/4);
    //printf("%.6f %.6f %.6f %.6f\n",S1,S2,t1,t2);

    t1 = (-v0+sqrt( fabs( sqr(v0) + 2*a*S1)) )/a;
    //printf(" sqrt = %f\n",sqr(v0)+ 2*a*S1);
    //printf("%.6f %.6f %.6f %.6f\n",S1,S2,t1,t2);
    double v2 = t1*a+v0;
    t2 = ( v2-sqrt( fabs( sqr(v2) - 2*a*S2)) )/a;
    //printf("%.6f %.6f %.6f %.6f\n",S1,S2,t1,t2);
    t=t1+t2;
}

point turn_right(point a)
{
    point ret = a;
    swap(ret.x,ret.y);
    ret.y=-ret.y;
    return ret;
}

double mulx(point a,point b)
{
    return a.x*b.y - a.y*b.x;
}

bool judge(Segment x,Segment y)
{
    point v2 = turn_right( x.vec );
    point v3;
    v3.x = y.st.x - x.ed.x;
    v3.y = y.st.y - x.ed.y;
    //printf("mx = %f\n",mulx(v2,v3));
    if( mulx(v2,v3) >= -eps )
    {
        return true;
    }
    else
    {
        return false;
    }
}
void gao()
{
    for(int i=0; i<n-1; ++i)
    {
        double r = get_r(S[i],S[i+1]);
        //printf(" %f,%f   r = %.7f\n",S[i].st.x,S[i].st.y,r);
        S[i].mxe = sqrt( r*a );
        //printf("mxe = %f\n",S[i].mxe);
    }
    S[n-1].mxe=0;
    double v0=0,v,t;
    for(int i=n-1; i>=0; --i)
    {
        v0=S[i].mxe;
        S[i].mxs = sqrt(sqr(v0)+2.0*a*S[i].len);
        if(i>0&&S[i].mxs<S[i-1].mxe)S[i-1].mxe=S[i].mxs;
    }
    for(int i=0; i<n; ++i)
    {
        //printf("%.6f %.6f\n",S[i].mxs,S[i].mxe);
    }
    res=0;
    double v1;
    v0=0;
    for(int i=0; i<n; ++i)
    {
        gao(S[i].mxs,S[i].mxe,S[i].len,v0,v1,t);
        if(i+1<n)
        {
            double r = get_r(S[i],S[i+1]);
            double cos = get_cos(S[i],S[i+1]);
            //printf("r = %f cos=%f\n",r,cos);
            if( fabs(cos)<eps )
            {
                //printf("cosa=%f\n",1.0);
                if(judge(S[i],S[i+1]))
                {
                    //printf("small\n");
                    t += PI*r/v1/2.0;
                }
                else
                {
                    //printf("big\n");
                    t += 3.0/2.0*PI*r/v1;
                }
            }
            else if( fabs(fabs(cos)-1)<eps )
            {
                //printf("sem\n");
                t += PI/v1*r;
            }
            else while(1);
            //printf("r = %f\n",r);
        }
        v0=v1;
        res += t;
        //printf("res = %.6f\n",res);
    }
}
int main()
{
    //freopen("10.in","r",stdin);
    while(~scanf("%d%lf",&n,&a))
    {
        double sx,sy,ex,ey;
        for(int i=0; i<n; ++i)
        {
            scanf("%lf %lf %lf %lf",&sx,&sy,&ex,&ey);
            S[i].st.x=sx;
            S[i].st.y=sy;
            S[i].ed.x=ex;
            S[i].ed.y=ey;
            S[i].pre();
            //printf("%f,%f -> %f,%f\n",S[i].st.x,S[i].st.y,S[i].ed.x,S[i].ed.y);
        }
        gao();
        printf("%.8f\n",res);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 7316
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
const double eps = 0.000001;
const double PI = acos(-1);
const double INF = 1000;
struct point{
  double x, y;
  point(){
  }
  point(double x, double y): x(x), y(y){
  }
  point operator +(point P){
    return point(x + P.x, y + P.y);
  }
  point operator -(point P){
    return point(x - P.x, y - P.y);
  }
  point operator *(double k){
    return point(x * k, y * k);
  }
  point operator /(double k){
    return point(x / k, y / k);
  }
};
point rotate90(point P){
  return point(-P.y, P.x);
}
double abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
double angle(point P){
  return atan2(P.y, P.x);
}
struct line{
  point A, B;
  line(){
  }
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
bool is_parallel(line L1, line L2){
  return abs(cross(vec(L1), vec(L2))) < eps;
}
point line_intersection(line L1, line L2){
  return L1.A + vec(L1) * cross(L2.A - L1.A, vec(L2)) / cross(vec(L1), vec(L2));
}
int main(){
  cout << fixed << setprecision(20);
  int N;
  double a;
  cin >> N >> a;
  vector<line> L(N);
  for (int i = 0; i < N; i++){
    cin >> L[i].A.x >> L[i].A.y >> L[i].B.x >> L[i].B.y;
  }
  vector<double> l(N);
  for (int i = 0; i < N; i++){
    l[i] = abs(vec(L[i]));
  }
  vector<point> C(N - 1);
  for (int i = 0; i < N - 1; i++){
    if (is_parallel(L[i], L[i + 1])){
      C[i] = (L[i].B + L[i + 1].A) / 2;
    } else {
      line L1(L[i].B, L[i].B + rotate90(vec(L[i])));
      line L2(L[i + 1].A, L[i + 1].A + rotate90(vec(L[i + 1])));
      C[i] = line_intersection(L1, L2);
    }
  }
  vector<double> r(N - 1), t(N - 1);
  for (int i = 0; i < N - 1; i++){
    r[i] = dist(L[i].B, C[i]);
    t[i] = angle(vec(L[i + 1])) - angle(vec(L[i]));
    if (t[i] < 0){
      t[i] += 2 * PI;
    }
    if (cross(vec(L[i]), C[i] - L[i].A) < 0){
      t[i] = 2 * PI - t[i];
    }
  }
  vector<double> v(N + 1);
  v[0] = 0;
  v[N] = 0;
  for (int i = 0; i < N - 1; i++){
    v[i + 1] = sqrt(a * r[i]);
  }
  for (int i = 0; i < N; i++){
    v[i + 1] = min(v[i + 1], sqrt(v[i] * v[i] + 2 * a * l[i]));
  }
  for (int i = N - 1; i >= 0; i--){
    v[i] = min(v[i], sqrt(v[i + 1] * v[i + 1] + 2 * a * l[i]));
  }
  double ans = 0;
  for (int i = 0; i < N; i++){
    double w = sqrt((2 * a * l[i] + v[i] * v[i] + v[i + 1] * v[i + 1]) / 2);
    ans += (w - v[i]) / a;
    ans += (w - v[i + 1]) / a;
  }
  for (int i = 0; i < N - 1; i++){
    ans += r[i] * t[i] / v[i + 1];
  }
  cout << ans << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 6372
final_rank: 7

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
#include<chrono>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;

template<typename T>
void chmin(T& a, T b) {
	a = min(a, b);
}
template<typename T>
void chmax(T& a, T b) {
	a = max(a, b);
}
template<typename T>
void cinarray(vector<T>& v) {
	rep(i, v.size())cin >> v[i];
}
template<typename T>
void coutarray(vector<T>& v) {
	rep(i, v.size()) {
		if (i > 0)cout << " "; cout << v[i];
	}
	cout << "\n";
}
ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	if (x == 0)return 0;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	int n;
	modint() :n(0) { ; }
	modint(ll m) {
		if (m < 0 || mod <= m) {
			m %= mod; if (m < 0)m += mod;
		}
		n = m;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 10;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

ll gcd(ll a, ll b) {
	a = abs(a); b = abs(b);
	if (a < b)swap(a, b);
	while (b) {
		ll r = a % b; a = b; b = r;
	}
	return a;
}

typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };

typedef complex<ld> Point;
ld dot(Point a, Point b) { return real(conj(a) * b); }
ld cross(Point a, Point b) { return imag(conj(a) * b); }
namespace std {
	bool operator<(const Point& lhs, const Point& rhs) {
		return lhs.real() == rhs.real() ? lhs.imag() < rhs.imag() : lhs.real() < rhs.real();
	}
}
struct Line {
	Point a, b;
};
struct Circle {
	Point p; ld r;
};
int ccw(Point a, Point b, Point c) {
	b -= a; c -= a;
	if (cross(b, c) > eps)return 1;//counter clockwise
	if (cross(b, c) < -eps)return -1;//clock wise
	if (dot(b, c) < 0)return 2;//c--a--b on line
	if (norm(b) < norm(c))return -2;//a--b--c on line
	return 0; //a--c--b on line
}
bool eq(ld a, ld b) {
	return abs(a - b) < eps;
}
//2直線の交差判定
bool isis_ll(Line l, Line m) {
	return !eq(cross(l.b - l.a, m.b - m.a), 0);
}
//直線と線分の交差判定
bool isis_ls(Line l, Line s) {
	return (cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < eps);
}
//点が直線上に存在するか
bool isis_lp(Line l, Point p) {
	return (abs(cross(l.b - p, l.a - p)) < eps);
}
//点が線分上に存在するか
bool isis_sp(Line s, Point p) {
	//誤差がisis_lpに比べて大きいので、できるだけisis_lpを使う
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}
//線分と線分の交差判定
//bool isis_ss(Line s, Line t) {
//	return(cross(s.b - s.a, t.a - s.a)*cross(s.b - s.a, t.b - s.a) < -eps && cross(t.b - t.a, s.a - t.a)*cross(t.b - t.a, s.b - t.a) < -eps);
//}
//線分と線分の交差判定2
bool isis_ss(Line s, Line t) {
	return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}
//点から直線への垂線の足
Point proj(Line l, Point p) {
	ld t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + t * (l.a - l.b);
}
//直線と直線の交点
//平行な２直線に対しては使うな！！！！
Point is_ll(Line s, Line t) {
	Point sv = s.b - s.a; Point tv = t.b - t.a;
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}
//直線と点の距離
ld dist_lp(Line l, Point p) {
	return abs(p - proj(l, p));
}
//直線と直線の距離
ld dist_ll(Line l, Line m) {
	return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}
//線分と直線の距離
ld dist_ls(Line l, Line s) {
	return isis_ls(l, s) ? 0 : min(dist_lp(l, s.a), dist_lp(l, s.b));
}
//線分と点の距離
ld dist_sp(Line s, Point p) {
	Point r = proj(s, p);
	return isis_sp(s, r) ? abs(p - r) : min(abs(p - s.a), abs(p - s.b));
}
//線分と線分の距離
ld dist_ss(Line s, Line t) {
	if (isis_ss(s, t))return 0;
	return min({ dist_sp(s,t.a),dist_sp(s,t.b),dist_sp(t,s.a),dist_sp(t,s.b) });
}

void solve() {
	int n, ma; cin >> n >> ma;
	auto calc = [&](ld v, ld len) {
		return sqrt(v * v + 2 * ma * len);
	};
	vector<Line> vl(n);
	rep(i, n) {
		int x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		vl[i] = { {(ld)x1,(ld)y1},{(ld)x2,(ld)y2} };
	}
	vector<ld> lens(n);
	rep(i, n)lens[i] = abs(vl[i].b - vl[i].a);
	vector<ld> rad(n - 1);
	vector<ld> rlen(n - 1);
	rep(i, n - 1) {
		if (!isis_ll(vl[i], vl[i + 1])) {
			rad[i] = abs(vl[i].b - vl[i + 1].a) / 2;
			rlen[i] = rad[i] * pi;
			continue;
		}
		Point p = is_ll(vl[i], vl[i + 1]);
		ld d = abs(p - vl[i].b);
		Point d1 = vl[i].a - vl[i].b;
		Point d2 = vl[i+1].b - vl[i+1].a;
		ld t = acos(dot(d1, d2) / abs(d1) / abs(d2));
		rad[i] = d * tan(t / 2);
		if (dot(vl[i].b - vl[i].a, p - vl[i].b) > 0) {
			rlen[i] = rad[i] * (pi - t);
		}
		else {
			rlen[i] = rad[i] * (pi + t);
		}
	}
	vector<ld> dist(n + 1, INF);
	using speP = pair<ld, int>;
	priority_queue<speP, vector<speP>, greater<speP>> q;
	dist[0] = 0; q.push({ 0,0 });
	dist[n] = 0; q.push({ 0,n });
	rep(i, n - 1) {
		dist[i + 1] = sqrt(rad[i] * ma);
		q.push({ rad[i] * ma,i + 1 });
	}
	while (!q.empty()) {
		speP p = q.top(); q.pop();
		int id = p.second;
		if (p.first > dist[id])continue;
		if (id < n) {
			ld nd = calc(p.first, lens[id]);
			if (nd < dist[id + 1]) {
				dist[id + 1] = nd;
				q.push({ nd,id + 1 });
			}
		}
		if (id > 0) {
			ld nd = calc(p.first, lens[id - 1]);
			if (nd < dist[id - 1]) {
				dist[id - 1] = nd;
				q.push({ nd,id - 1 });
			}
		}
	}
	//coutarray(rlen);
	ld ans = 0;
	rep(i, n - 1) {
		ans += rlen[i] / dist[i + 1];
	}
	auto calcsegs = [&](ld v, ld len) {
		return 2 * (-v + sqrt(v * v + ma * len)) / ma;
	};
	auto calcseg = [&](ld sv, ld gv, ld len) {
		if (sv > gv)swap(sv, gv);
		ld res = 0;
		ld dif = gv - sv;
		ld ct = dif / ma;
		res += ct;
		len -= (sv + gv) * ct / 2;
		res += calcsegs(gv, len);
		return res;
	};
	rep(i, n) {
		ans += calcseg(dist[i], dist[i + 1], lens[i]);
	}
	cout << ans << "\n";
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(8);
	//init_f();
	//init();
	//while(true)
	//expr();
	//int t; cin >> t; rep(i, t)
	solve();
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 10236
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
const double eps = 0.000001;
const double PI = acos(-1);
const double INF = 1000;
struct point{
  double x, y;
  point(){
  }
  point(double x, double y): x(x), y(y){
  }
  point operator +(point P){
    return point(x + P.x, y + P.y);
  }
  point operator -(point P){
    return point(x - P.x, y - P.y);
  }
  point operator *(double k){
    return point(x * k, y * k);
  }
  point operator /(double k){
    return point(x / k, y / k);
  }
};
point rotate90(point P){
  return point(-P.y, P.x);
}
double abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
double angle(point P){
  return atan2(P.y, P.x);
}
struct line{
  point A, B;
  line(){
  }
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
bool is_parallel(line L1, line L2){
  return abs(cross(vec(L1), vec(L2))) < eps;
}
point line_intersection(line L1, line L2){
  return L1.A + vec(L1) * cross(L2.A - L1.A, vec(L2)) / cross(vec(L1), vec(L2));
}
int main(){
  cout << fixed << setprecision(20);
  int N;
  double a;
  cin >> N >> a;
  vector<line> L(N);
  for (int i = 0; i < N; i++){
    cin >> L[i].A.x >> L[i].A.y >> L[i].B.x >> L[i].B.y;
  }
  vector<double> l(N);
  for (int i = 0; i < N; i++){
    l[i] = abs(vec(L[i]));
  }
  vector<point> C(N - 1);
  for (int i = 0; i < N - 1; i++){
    if (is_parallel(L[i], L[i + 1])){
      C[i] = (L[i].B + L[i + 1].A) / 2;
    } else {
      line L1(L[i].B, L[i].B + rotate90(vec(L[i])));
      line L2(L[i + 1].A, L[i + 1].A + rotate90(vec(L[i + 1])));
      C[i] = line_intersection(L1, L2);
    }
  }
  vector<double> r(N - 1), t(N - 1);
  for (int i = 0; i < N - 1; i++){
    r[i] = dist(L[i].B, C[i]);
    t[i] = angle(vec(L[i + 1])) - angle(vec(L[i]));
    if (t[i] < 0){
      t[i] += 2 * PI;
    }
    if (cross(vec(L[i]), C[i] - L[i].A) < 0){
      t[i] = 2 * PI - t[i];
    }
  }
  vector<double> v(N + 1);
  v[0] = 0;
  v[N] = 0;
  for (int i = 0; i < N - 1; i++){
    v[i + 1] = sqrt(a * r[i]);
  }
  for (int i = 0; i < N; i++){
    v[i + 1] = min(v[i + 1], sqrt(v[i] * v[i] + 2 * a * l[i]));
  }
  for (int i = N - 1; i >= 0; i--){
    v[i] = min(v[i], sqrt(v[i + 1] * v[i + 1] + 2 * a * l[i]));
  }
  double ans = 0;
  for (int i = 0; i < N; i++){
  	double w = sqrt((2 * a * l[i] + v[i] * v[i] + v[i + 1] * v[i + 1]) / 2);
  	ans += (w - v[i]) / a;
  	ans += (w - v[i + 1]) / a;
  }
  for (int i = 0; i < N - 1; i++){
    ans += r[i] * t[i] / v[i + 1];
  }
  cout << ans << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 6432
final_rank: 8

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 40005


struct Point{
	Point(double arg_x,double arg_y){
		x = arg_x;
		y = arg_y;
	}

	Point(){
		x = y = 0.0;
	}

	Point operator + (Point p){ return Point(x+p.x,y+p.y); }
	Point operator - (Point p){ return Point(x-p.x,y-p.y);}
	Point operator * (double a){ return Point(a*x,a*y); }
	Point operator / (double a){ return Point(x/a,y/a); }

	double abs(){ return sqrt(norm()); }
	double norm(){ return x*x + y*y; }

	bool operator<(const Point &p) const{
		return x != p.x? x < p.x: y < p.y;
	}

	bool operator == (const Point &p) const{
		return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
	}

   	/*
	void debug(){

		printf("(%.3lf,%.3lf)\n",x,y);
	}*/

	double x,y;
};


typedef Point Vector;
typedef vector<Point> Polygon;

struct Line{
	Line(){
		len = 0;
	}
	Line(Point a,Point b){
		p[0] = a;
		p[1] = b;
		len = 0;
	}
	/*void outPut(){

		printf("(%.3lf,%.3lf)-(%.3lf,%.3lf)\n",p[0].x,p[0].y,p[1].x,p[1].y);
	}*/
	Point p[2];
	double len;
};

struct Corner{

	double r,len;
};

int N;
double A;
double NUM = 100000;
Line line[SIZE];
Corner corner[SIZE];
double L_limit[SIZE],C_limit[SIZE];
double L_mid[SIZE];


double calc_dist(Point A,Point B){

	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}


double norm(Vector a){
	return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
	return sqrt(norm(a));
}

double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

double dot(Vector a,Vector b){
    return a.x*b.x + a.y*b.y;
}

int func(double x1,double y1,double x2, double y2, double xp, double yp){
	double naiseki,norm1,norm2,gaiseki;
	norm1 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
	norm2 = sqrt((xp-x1)*(xp-x1)+(yp-y1)*(yp-y1));
	naiseki = (xp-x1)*(x2-x1)+(yp-y1)*(y2-y1);
	gaiseki = (x2-x1)*(yp-y1)-(xp-x1)*(y2-y1);
	if(gaiseki > EPS){
		return 1;
	}else if(gaiseki < -EPS){
		return -1;
	}
	if(naiseki < -EPS){
		return 2;
	}

	if(norm1 < norm2){
		return -2;
	}
	return 0;
}


//★★直線ではなく、線分の交差判定★★
bool is_Cross(Line a,Line b){

	if(func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[0].x,b.p[0].y)*
			func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[1].x,b.p[1].y) <= 0 &&
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[0].x,a.p[0].y)*
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[1].x,a.p[1].y) <= 0){
		return true;
	}
	return false;
}

double calc_slope(Line A){

	if(fabs(A.p[0].x-A.p[1].x) < EPS){

		return DBL_MAX;

	}else if(fabs(A.p[0].y-A.p[1].y) < EPS){

		return 0;

	}else{

		return (A.p[1].y-A.p[0].y)/(A.p[1].x-A.p[0].x);
	}
}

Point calc_minus(Point a,Point b){
    Point ret;

    ret.x = a.x-b.x;
    ret.y = a.y-b.y;

    return ret;
}

double calc_len(Vector a){
    return sqrt(a.x*a.x+a.y*a.y);
}

//線分ではなく直線と点の距離
double getDistanceLP(Line l,Point p){
    return fabs(cross(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0]))/calc_len(calc_minus(l.p[1],l.p[0])));
}

//点と線分の距離
double getDistanceSP(Line l,Point p){
	if(dot(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0])) < 0.0)return calc_len(calc_minus(p,l.p[0]));
	if(dot(calc_minus(l.p[0],l.p[1]),calc_minus(p,l.p[1])) < 0.0)return calc_len(calc_minus(p,l.p[1]));
	return getDistanceLP(l,p);
}

//線分と線分の距離
double getDistance(Line A,Line B){
	if(is_Cross(A,B))return 0.0;
	return min(min(getDistanceSP(A,B.p[0]),getDistanceSP(A,B.p[1])),
			min(getDistanceSP(B,A.p[0]),getDistanceSP(B,A.p[1])));
}


//交点を求める関数
Point calc_Cross_Point(double x1,double x2,double x3,double x4,double y1,double y2,double y3,double y4){
	Point ret;
	ret.x = ((x2-x1)*(y3*(x4-x3)+x3*(y3-y4))-(x4-x3)*(y1*(x2-x1)+x1*(y1-y2)))/((y2-y1)*(x4-x3)-(y4-y3)*(x2-x1));
	if(fabs(x1-x2) > EPS){
		ret.y = ((y2-y1)*ret.x+y1*(x2-x1)+x1*(y1-y2))/(x2-x1);
	}else{
		ret.y = ((y4-y3)*ret.x+y3*(x4-x3)+x3*(y3-y4))/(x4-x3);
	}
	return ret;
}

//インタフェース関数
Point calc_Cross_Point(Point a,Point b,Point c,Point d){
	return calc_Cross_Point(a.x,b.x,c.x,d.x,a.y,b.y,c.y,d.y);
}

Point calc_Cross_Point(Line A,Line B){

	if(getDistanceSP(B,A.p[0]) < EPS){

		return A.p[0];

	}else if(getDistanceSP(B,A.p[1]) < EPS){

		return A.p[1];

	}else if(getDistanceSP(A,B.p[0]) < EPS){

		return B.p[0];

	}else if(getDistanceSP(A,B.p[1]) < EPS){

		return B.p[1];
	}

	return calc_Cross_Point(A.p[0],A.p[1],B.p[0],B.p[1]);
}


int main(){

	scanf("%d %lf",&N,&A);

	for(int i = 0; i < N; i++){

		scanf("%lf %lf %lf %lf",&line[i].p[0].x,&line[i].p[0].y,&line[i].p[1].x,&line[i].p[1].y);
		line[i].len = calc_dist(line[i].p[0],line[i].p[1]);
	}

	Point center;
	double r,rad;

	Line line1,line2;
	Vector vec1,vec2;

	//円弧の計算
	for(int i = 0; i < N-1; i++){

		double slope1 = calc_slope(line[i]);
		double slope2 = calc_slope(line[i+1]);

		if(fabs(slope1-slope2) < EPS){ //平行

			center = (line[i].p[1]+line[i+1].p[0])/2;
			r = calc_dist(center,line[i].p[1]);
			rad = M_PI;

		}else{

			if(fabs(slope1-DBL_MAX) < EPS){ //垂直

				line1 = Line(Point(-NUM,line[i].p[1].y),Point(NUM,line[i].p[1].y));

			}else if(fabs(slope1) < EPS){ //水平

				line1 = Line(Point(line[i].p[1].x,-NUM),Point(line[i].p[1].x,NUM));

			}else{

				double tmp_slope = (-1.0)/slope1;
				line1 = Line(Point(line[i].p[1].x-NUM,line[i].p[1].y-NUM*tmp_slope),Point(line[i].p[1].x+NUM,line[i].p[1].y+NUM*tmp_slope));
			}

			if(fabs(slope2-DBL_MAX) < EPS){ //垂直

				line2 = Line(Point(-NUM,line[i+1].p[0].y),Point(NUM,line[i+1].p[0].y));

			}else if(fabs(slope2) < EPS){ //水平

				line2 = Line(Point(line[i+1].p[0].x,-NUM),Point(line[i+1].p[0].x,NUM));

			}else{

				double tmp_slope = (-1.0)/slope2;
				line2 = Line(Point(line[i+1].p[0].x-NUM,line[i+1].p[0].y-NUM*tmp_slope),Point(line[i+1].p[0].x+NUM,line[i+1].p[0].y+NUM*tmp_slope));
			}

			center = calc_Cross_Point(line1,line2);
			r = calc_dist(center,line[i].p[1]);

			vec1 = line[i].p[1]-center;
			vec2 = line[i+1].p[0]-center;

			rad = acos(dot(vec1,vec2)/(abs(vec1)*abs(vec2)));

			line1.p[1] = line[i].p[1];

			//line[i]とline[i+1]を非円弧方向に伸ばし、交差するかどうかみる
			if(fabs(slope1-DBL_MAX) < EPS){ //垂直

				if(line[i].p[1].y > line[i].p[0].y){

					line1.p[0] = Point(line[i].p[1].x,-NUM);

				}else{

					line1.p[0] = Point(line[i].p[1].x,NUM);
				}

			}else if(fabs(slope1) < EPS){ //水平

				if(line[i].p[1].x > line[i].p[0].x){

					line1.p[0] = Point(-NUM,line[i].p[1].y);
				}else{

					line1.p[0] = Point(NUM,line[i].p[1].y);
				}

			}else{

				if(line[i].p[1].x > line[i].p[0].x){

					line1.p[0] = Point(line[i].p[1].x-NUM,line[i].p[1].y-NUM*slope1);
				}else{

					line1.p[0] = Point(line[i].p[1].x+NUM,line[i].p[1].y+NUM*slope1);
				}
			}

			line2.p[0] = line[i+1].p[0];

			if(fabs(slope2-DBL_MAX) < EPS){ //垂直

				if(line[i+1].p[0].y > line[i+1].p[1].y){

					line2.p[1] = Point(line[i+1].p[0].x,-NUM);

				}else{

					line2.p[1] = Point(line[i+1].p[0].x,NUM);
				}

			}else if(fabs(slope2) < EPS){ //水平

				if(line[i+1].p[0].x > line[i+1].p[1].x){

					line2.p[1] = Point(-NUM,line[i+1].p[0].y);
				}else{

					line2.p[1] = Point(NUM,line[i+1].p[0].y);
				}

			}else{

				if(line[i+1].p[0].x > line[i+1].p[1].x){

					line2.p[1] = Point(line[i+1].p[0].x-NUM,line[i+1].p[0].y-NUM*slope2);
				}else{

					line2.p[1] = Point(line[i+1].p[0].x+NUM,line[i+1].p[0].y+NUM*slope2);
				}
			}

			if(is_Cross(line1,line2)){

				rad = 2*M_PI-rad;
			}
		}

		corner[i].r = r;
		corner[i].len = r*rad;
	}

	double tmp_dist,max_corner_v,max_v_sub;

	//ダミーコーナー(line[i-1]の先に長さ0のコーナーが繋がっているとする)
	C_limit[N-1] = 0;

	//終点から始点に向かってコーナーの制限速度を求める
	//各コーナーの速度の上限値(最大値を求めるので、次のコーナーとの間に位置する直線の加速度は-Aとする)
	for(int i = N-2; i >= 0; i--){

		//次のコーナーまでの距離
		tmp_dist = line[i+1].len;
		//円弧の速度の最大値
		max_corner_v = sqrt(A*corner[i].r);

		//その後の直線で原則する場合の制限速度
		max_v_sub = sqrt(C_limit[i+1]*C_limit[i+1]+2*A*tmp_dist);

		C_limit[i] = min(max_corner_v,max_v_sub);
	}

	//始点から終点に向かってコーナーの制限速度を求める(加速度A)
	double max_v_add;

	for(int i = 1; i <= N-1; i++){

		//前のコーナーからの距離
		tmp_dist = line[i].len;
		max_v_add = sqrt(C_limit[i-1]*C_limit[i-1]+2*A*tmp_dist);

		C_limit[i] = min(C_limit[i],max_v_add);
	}

	double ans = 0,max_v;

	//全力で加速してもコーナーの制限速度に達しないなら、全力で加速する
	max_v = sqrt(2*A*line[0].len);
	//直線のアクセス切り替えpointおよび必要時間を求める
	L_mid[0] = (min(max_v,C_limit[0])*min(max_v,C_limit[0])+2*A*line[0].len)/(4*A);
	double mid_v = sqrt(2*A*L_mid[0]);

	ans += mid_v/A;
	ans += (mid_v-min(max_v,C_limit[0]))/A;

	double v_pre,v_next;

	for(int i = 1; i <= N-1; i++){

		v_pre = C_limit[i-1];
		max_v = sqrt(2*A*line[i].len+v_pre*v_pre);

		v_next = min(max_v,C_limit[i]);

		L_mid[i] = (v_next*v_next-v_pre*v_pre+2*A*line[i].len)/(4*A);
		mid_v = sqrt(v_pre*v_pre+2*A*L_mid[i]);

		ans += (mid_v-v_pre)/A;
		ans += (mid_v-v_next)/A;
	}

	//円弧の時間
	for(int i = 0; i <= N-2; i++){

		ans += corner[i].len/C_limit[i];
	}

	printf("%.10lf\n",ans);

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 6020
final_rank: 2

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <set>
#include <cassert>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e12;
const double PI = acos(-1);
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : array<P, 2>{
    L(const P& a, const P& b){ at(0)=a; at(1)=b; }
    L(){}
};
namespace std{
    bool operator < (const P& a, const P& b){
        return !EQ(a.X,b.X) ? a.X<b.X : a.Y+EPS<b.Y;
    }
    bool operator == (const P& a, const P& b){
        return abs(a-b) < EPS;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}
int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b,c) > EPS) return +1; //ccw
    if(cross(b,c) < -EPS) return -1; //cw
    if(dot(b,c) < -EPS) return +2; //c-a-b
    if(abs(c)-abs(b) > EPS) return -2; //a-b-c
    return 0; //a-c-b
}

bool intersectSS(const L& a, const L& b){
    return ( ccw(a[0],a[1],b[0]) *ccw(a[0],a[1],b[1]) <= 0 ) &&
        ( ccw(b[0],b[1],a[0]) *ccw(b[0],b[1],a[1]) <= 0 );
}

bool isParallel(const P &a, const P &b){
    return abs(cross(a,b)) < EPS;
}
bool isParallel(const L &a, const L &b){
    return isParallel(a[1]-a[0], b[1]-b[0]);
}
P crosspointLL(const L &l, const L &m) {
  double A = cross(l[1]-l[0], m[1]-m[0]);
  double B = cross(l[1]-l[0], l[1]-m[0]);
  return m[0] + B/A *(m[1]-m[0]);
}

double getangle(P a, P b){
    return abs(arg(a/b));
}

int main(){
    int n;
    double amax;
    cin >> n >> amax;

    vector<L> l(n);
    vector<double> len(n);
    for(int i=0; i<n; i++){
        double xs,ys,xt,yt;
        cin >> xs >> ys >> xt >> yt;
        l[i] = L(P(xs, ys), P(xt, yt));
        len[i] = abs(l[i][1] -l[i][0]);
    }
    //i番目の線分の終点を通過するときの速度上限
    vector<double> vlimit(n);
    vlimit[n-1] = 0;
    vector<double> arclen(n-1);
    for(int i=n-2; i>=0; i--){
        double r;
        if(isParallel(l[i], l[i+1])){
            r = abs(l[i+1][0] -l[i][1]) /2.0;
            arclen[i] = PI *r;
        }else{
            //接合部分に向かう方向
            P dir[2] = {l[i][1] -l[i][0], l[i+1][0] -l[i+1][1]};    
            P ortdir[2] = {dir[0]*P(0, 1), dir[1]*P(0, 1)};
            L ortline[2] = {L(l[i][1], l[i][1] +ortdir[0]), L(l[i+1][0], l[i+1][0] +ortdir[1])};
            //円弧の中心
            P cp = crosspointLL(ortline[0], ortline[1]);
            r = abs(l[i][1] -cp);
            L ray[2] = {L(l[i][1], l[i][1] +1e4*dir[0]), L(l[i+1][0], l[i+1][0] +1e4*dir[1])};
            if(intersectSS(ray[0], ray[1])){
                arclen[i] = r *getangle(dir[0], dir[1]);
            }else{
                arclen[i] = r *(2*PI -getangle(dir[0], dir[1]));
            }
        }
        //カーブを曲がり切れる速度上限
        //a = v^2 /r より
        double v = sqrt(r *amax);
        //次以降のカーブを曲がり切れる速度上限
        //v^2 -(v_0)^2 = 2ax より
        double vrev = sqrt(2 *amax *len[i+1] +vlimit[i+1]*vlimit[i+1]);
        vlimit[i] = min(v, vrev);
    }

    double ans = 0;
    double v = 0;
    for(int i=0; i<n; i++){
        double clen = (vlimit[i]*vlimit[i] -v*v +2*amax*len[i]) /(4*amax);
        if(clen < 0 || len[i] < clen){
            //加減速のみ
            double acc = (vlimit[i] > v)? amax: -amax;
            double vend = sqrt(2 *acc *len[i] +v*v);
            ans += (vend -v) /acc;
            v = vend;
        }else{
            //加速のち減速
            double vmid = sqrt(2 *amax *clen +v*v);
            ans += (vmid -v) /amax + (vlimit[i] -vmid) /(-amax);
            v = vlimit[i];
        }
   
        //円運動中の時間を加算
        if(i < n-1){
            ans += arclen[i] /v;
        }
    }
    cout << fixed << setprecision(10);
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 5060
final_rank: 9

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld=long double;
ld eps=1e-9;


/* 幾何の基本 */

#include <complex>

typedef complex<ld> Point;


const ld pi = acos(-1.0);
const ld dtop = pi / 180.;
const ld ptod = 1. / dtop;

namespace std {
	bool operator<(const Point &lhs, const Point &rhs) {
		if (lhs.real() < rhs.real() - eps) return true;
		if (lhs.real() > rhs.real() + eps) return false;
		return lhs.imag() < rhs.imag();
	}
}

// 点の入力
Point input_Point() {
	ld x, y;
	cin >> x >> y;
	return Point(x, y);
}

// 誤差つき等号判定
bool eq(const ld a, const ld b) {
	return (abs(a - b) < eps);
}

// 内積
ld dot(const Point& a, const Point& b) {
	return real(conj(a) * b);
}

// 外積
ld cross(const Point& a, const Point& b) {
	return imag(conj(a) * b);
}

// 直線の定義
class Line {
public:
	Point a, b;
	Line() : a(Point(0, 0)), b(Point(0, 0)) {}
	Line(Point a, Point b) : a(a), b(b) {}
	Point operator[](const int _num)const {
		if (_num == 0)return a;
		else if (_num == 1)return b;
		else {
			assert(false);
			return Point();
		}
	}
};

// 円の定義
class Circle {
public:
	Point p;
	ld r;
	Circle() : p(Point(0, 0)), r(0) {}
	Circle(Point p, ld r) : p(p), r(r) {}
};

// ccw
// 1: a,b,cが反時計周りの順に並ぶ
//-1: a,b,cが時計周りの順に並ぶ
// 2: c,a,bの順に直線に並ぶ
//-2: a,b,cの順に直線に並ぶ
// 0: a,c,bの順に直線に並ぶ
int ccw(const Point& a, const Point &b, const Point &c) {
	const Point nb(b - a);
	const Point nc(c - a);
	if (cross(nb, nc) > eps) return 1;   // a,b,cが反時計周りの順に並ぶ
	if (cross(nb, nc) < -eps) return -1; // a,b,cが時計周りの順に並ぶ
	if (dot(nb, nc) < 0) return 2;       // c,a,bの順に直線に並ぶ
	if (norm(nb) < norm(nc)) return -2;  // a,b,cの順に直線に並ぶ
	return 0;                          // a,c,bの順に直線に並ぶ
}


/* 交差判定 */

// 直線と直線の交差判定
bool isis_ll(const Line& l, const Line& m) {
	return !eq(cross(l.b - l.a, m.b - m.a), 0);
}

// 直線と線分の交差判定
bool isis_ls(const Line& l, const Line& s) {
	return isis_ll(l, s) &&
		(cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < eps);
}

// 線分と線分の交差判定
bool isis_ss(const Line& s, const Line& t) {
	return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
		ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

// 点の直線上判定
bool isis_lp(const Line& l, const Point& p) {
	return (abs(cross(l.b - p, l.a - p)) < eps);
}

// 点の線分上判定
bool isis_sp(const Line& s, const Point& p) {
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}

// 垂線の足
Point proj(const Line &l, const Point& p) {
	ld t = dot(p - l.a, l.b - l.a) / norm(l.a - l.b);
	return l.a + t * (l.b - l.a);
}

//線対象の位置にある点
Point reflect(const Line &l, const Point &p) {
	Point pr = proj(l, p);
	return pr * 2.l - p;
}

// 直線と直線の交点
Point is_ll(const Line &s, const Line& t) {
	Point sv = s.b - s.a, tv = t.b - t.a;
	assert(cross(sv, tv) != 0);
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}
// 直線と直線の交点
vector<Point> is_ll2(const Line &s, const Line& t) {
	Point sv = s.b - s.a, tv = t.b - t.a;
	if (cross(sv, tv) != 0)return vector<Point>(1, is_ll(s, t));
	else {
		vector<Point>ans;
		for (int k = 0; k < 2; ++k) {
			if (isis_sp(s, t[k]) && find(ans.begin(), ans.end(), t[k]) == ans.end())ans.push_back(t[k]);
			if (isis_sp(t, s[k]) && find(ans.begin(), ans.end(), s[k]) == ans.end())ans.push_back(s[k]);
		}
		return ans;
	}
}
// 線分と線分の交点
//　重なってる部分あるとassert(false)
Point is_ss(const Line &s, const Line& t) {
	if (isis_ss(s, t)) {
		for (int k = 0; k < 2; ++k) {
			for (int l = 0; l < 2; ++l) {
				if (s[k] == t[l])return s[k];
			}
		}
		return is_ll(s, t);
	}
	else {
		//先にisis_ssしてね
		assert(false);
		return Point(0, 0);
	}
}
// 線分と線分の交点
vector<Point> is_ss2(const Line &s, const Line& t) {
	vector<Point> kouho(is_ll2(s, t));
	vector<Point>ans;
	for (auto p : kouho) {
		if (isis_sp(s, p) && isis_sp(t, p))ans.emplace_back(p);
	}
	return ans;
}
// 直線と点の距離
ld dist_lp(const Line& l, const Point& p) {
	return abs(p - proj(l, p));
}

//直線と直線の距離
ld dist_ll(const Line& l, const Line& m) {
	return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}

// 直線と線分の距離
ld dist_ls(const Line& l, const Line& s) {
	return isis_ls(l, s) ? 0 : min(dist_lp(l, s.a), dist_lp(l, s.b));
}

// 線分と点の距離
ld dist_sp(const Line& s, const Point& p) {
	Point r = proj(s, p);
	return isis_sp(s, r) ? abs(r - p) : min(abs(s.a - p), abs(s.b - p));
}

// 線分と線分の距離
ld dist_ss(const Line& s, const Line& t) {
	if (isis_ss(s, t)) return 0;
	return min({ dist_sp(s, t.a), dist_sp(s, t.b), dist_sp(t, s.a), dist_sp(t, s.b) });
}


//直線と直線の二等分線のベクトル
Line line_bisection(const Line &s, const Line &t) {
	const Point laglanju(is_ll(s, t));
	const Point avec = !(abs(laglanju - s[0])<eps) ? s[0] - laglanju : s[1] - laglanju;
	const Point bvec = !(abs(laglanju - t[0])<eps) ? t[0] - laglanju : t[1] - laglanju;

	return Line(laglanju, laglanju + (abs(bvec)*avec + abs(avec)*bvec) / (abs(avec) + abs(bvec)));
}
//点と点の垂直二等分線　aを左に見ながら
Line point_bisection(const Point&a, const Point&b) {
	const Point cen((a + b) / 2.l);
	const Point vec = (b - a)*Point(0, 1);
	return Line(cen, cen + vec);
}

//三つの点からなる外心
Point outer_center(const vector<Point>&ps) {
	assert(ps.size() == 3);
	Line l1 = point_bisection(ps[0], ps[1]);
	Line l2 = point_bisection(ps[1], ps[2]);
	return is_ll(l1, l2);
}


//三つの直線からなる内心
//三つの直線が並行でないことは確かめといてね
Point  inner_center(const vector<Line>&ls) {
	vector<Point>vertics;
	for (int i = 0; i <static_cast<int>(ls.size()); ++i) {
		vertics.push_back(is_ll(ls[i], ls[(i + 1) % 3]));
	}
	if (vertics[0] == vertics[1] || vertics[1] == vertics[2] || vertics[2] == vertics[0])return vertics[0];
	Line bi1(line_bisection(Line(vertics[0], vertics[1]), Line(vertics[0], vertics[2])));
	Line bi2(line_bisection(Line(vertics[1], vertics[2]), Line(vertics[1], vertics[0])));
	if (bi1[0] == bi2[0])return bi1[0];
	else {
		return is_ll(bi1, bi2);
	}
}

//三つの直線からなる傍心
//三つの直線が並行でないことは確かめといてね
vector<Point>  ex_center(const vector<Line>&ls) {
	vector<Point>vertics;
	for (int i = 0; i < static_cast<int>(ls.size()); ++i) {
		vertics.push_back(is_ll(ls[i], ls[(i + 1) % 3]));
	}
	if (abs(vertics[0] - vertics[1])<eps || abs(vertics[1] - vertics[2])<eps || (abs(vertics[2] - vertics[0])<eps))return vector<Point>();
	vector<Point>ecs;
	for (int i = 0; i < 3; ++i) {
		Line bi1(line_bisection(Line(vertics[i], vertics[i] * 2.0l - vertics[(i + 2) % 3]), Line(vertics[i], vertics[(i + 1) % 3])));
		Line bi2(line_bisection(Line(vertics[(i + 1) % 3], vertics[(i + 1) % 3] * 2.0l - vertics[(i + 2) % 3]), Line(vertics[(i + 1) % 3], vertics[i])));
		ecs.push_back(is_ll(bi1, bi2));
	}
	return ecs;
}


//a,b:並行
//c:並行でない
//三つの直線から同距離の位置を求める。
vector<Point>  same_dis(const vector<Line>&ls) {
	vector<Point>vertics;
	vertics.push_back(is_ll(ls[0], ls[2]));
	vertics.push_back(is_ll(ls[1], ls[2]));

	if (abs(vertics[0] - vertics[1]) < eps)return vector<Point>{vertics[0]};
	Line bis(line_bisection(ls[0], ls[1]));
	vector<Point>ecs;

	Line abi(line_bisection(Line(vertics[0], vertics[1]), ls[0]));
	ecs.push_back(is_ll(bis, abi));


	Line bbi(line_bisection(Line(vertics[0], 2.l*vertics[0] - vertics[1]), ls[0]));
	ecs.push_back(is_ll(bis, bbi));

	return ecs;
}
/* 円 */

// 円と円の交点
vector<Point> is_cc(const Circle& c1, const Circle& c2) {
	vector<Point> res;
	ld d = abs(c1.p - c2.p);
	ld rc = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
	ld dfr = c1.r * c1.r - rc * rc;
	if (abs(dfr) < eps) dfr = 0.0;
	else if (dfr < 0.0) return res; // no intersection
	ld rs = sqrt(dfr);
	Point diff = (c2.p - c1.p) / d;
	res.push_back(c1.p + diff * Point(rc, rs));
	if (dfr != 0.0) res.push_back(c1.p + diff * Point(rc, -rs));
	return res;
}

/*
点が円の中にいるか
0 => out
1 => on
2 => in*/
int is_in_Circle(const  Point& p, const Circle &cir) {
	ld dis = abs(cir.p - p);
	if (dis > cir.r + eps)return 0;
	else if (dis < cir.r - eps)return 2;
	else return 1;
}
int is_in_Circle(const Circle &cir, const  Point& p) {
	ld dis = abs(cir.p - p);
	if (dis > cir.r + eps)return 0;
	else if (dis < cir.r - eps)return 2;
	else return 1;
}
/*
円lcが円rcの中にいるか
0 => out
1 => on
2 => in*/
int Circle_in_Circle(const Circle &lc, const  Circle&rc) {
	ld dis = abs(lc.p - rc.p);
	if (dis < rc.r - lc.r - eps)return 2;
	else if (dis>rc.r - lc.r + eps)return 0;
	else return 1;
}

// 円と直線の交点
vector<Point> is_lc(const Circle& c, const Line& l) {
	vector<Point> res;
	ld d = dist_lp(l, c.p);
	if (d < c.r + eps) {
		ld len = (d > c.r) ? 0.0 : sqrt(c.r * c.r - d * d); //safety;
		Point nor = (l.a - l.b) / abs(l.a - l.b);
		res.push_back(proj(l, c.p) + len * nor);
		res.push_back(proj(l, c.p) - len * nor);
	}
	return res;
}

// 円と線分の距離
vector<Point> is_sc(const Circle& c, const Line& l) {
	vector<Point> v = is_lc(c, l), res;
	for (Point p : v)
		if (isis_sp(l, p)) res.push_back(p);
	return res;
}

// 円と点の接線
vector<Line> tangent_cp(const Circle& c, const Point& p) {
	vector<Line> ret;
	Point v = c.p - p;
	ld d = abs(v);
	ld l = sqrt(norm(v) - c.r * c.r);
	if (isnan(l)) { return ret; }
	Point v1 = v * Point(l / d, c.r / d);
	Point v2 = v * Point(l / d, -c.r / d);
	ret.push_back(Line(p, p + v1));
	if (l < eps) return ret;
	ret.push_back(Line(p, p + v2));
	return ret;
}

// 円と円の接線
vector<Line> tangent_cc(const Circle& c1, const Circle& c2) {
	vector<Line> ret;
	if (abs(c1.p - c2.p) - (c1.r + c2.r) > -eps) {
		Point center = (c1.p * c2.r + c2.p * c1.r) / (c1.r + c2.r);
		ret = tangent_cp(c1, center);
	}
	if (abs(c1.r - c2.r) > eps) {
		Point out = (-c1.p * c2.r + c2.p * c1.r) / (c1.r - c2.r);
		vector<Line> nret = tangent_cp(c1, out);
		ret.insert(ret.end(), nret.begin(), nret.end());
	}
	else {
		Point v = c2.p - c1.p;
		v /= abs(v);
		Point q1 = c1.p + v * Point(0, 1) * c1.r;
		Point q2 = c1.p + v * Point(0, -1) * c1.r;
		ret.push_back(Line(q1, q1 + v));
		ret.push_back(Line(q2, q2 + v));
	}
	return ret;
}
//二つの円の重なり面積
ld two_Circle_area(const Circle&l, const Circle&r) {
	ld dis = abs(l.p - r.p);
	if (dis > l.r + r.r)return 0;
	else if (dis + r.r < l.r) {
		return r.r*r.r*pi;
	}
	else if (dis + l.r < r.r) {
		return l.r*l.r*pi;
	}
	else {
		ld ans = (l.r)*(l.r)*acos((dis*dis + l.r*l.r - r.r*r.r) / (2 * dis*l.r)) +
			(r.r)*(r.r)*acos((dis*dis + r.r*r.r - l.r*l.r) / (2 * dis*r.r)) -
			sqrt(4 * dis*dis*l.r*l.r - (dis*dis + l.r*l.r - r.r*r.r)*(dis*dis + l.r*l.r - r.r*r.r)) / 2;
		return ans;
	}

}

//0~2π
//ベクトルa から反時計回りに Θ 回ると　b　になる
ld gettheta(const Point&a, const Point &b) {
	ld adot = dot(a, b) / abs(a) / abs(b);
	if (adot > 1)adot -= eps;
	if (adot < -1)adot += eps;
	ld theta = acos(adot);
	ld dd = cross(a, b);
	return cross(a, b)>-eps ? theta : 2 * pi - theta;
}
 vector<ld>quad_equa(ld a, ld b, ld c) {
	ld root = b*b - 4 * a*c;
	if (abs(root) < eps) {
		ld ans = -b / (2 * a);
		return vector<ld>(2, ans);
	}
	else if (root > 0) {
		ld ans = -b / (2 * a);
		vector<ld>anss(2);
		anss[0] = ans + sqrt(root) / (2 * a);
		anss[1] = ans - sqrt(root) / (2 * a);
		if (anss[0] > anss[1])swap(anss[0], anss[1]);
		return anss;
	}
	else {
		return vector<ld>();
	}
}
ld getr(ld A,ld l, ld len) {
	ld k=quad_equa(A,2*l,-2*len)[1];
	return l+A*k;
}

ld get_time(ld A,ld l, ld r, ld len) {
	ld p=sqrt(A*len+(r*r+l*l)/2);
	return ((p-l)+(p-r))/A;
}

ld solve(ld A,vector<ld>straights, vector<pair<ld, ld>>arcs) {
	vector<ld>vels(arcs.size(),-1);

	priority_queue<pair<ld,int>>que;

	
	for (int i = 0; i < arcs.size(); ++i) {
		que.push(make_pair(-arcs[i].first,i));
	}

	while (!que.empty()) {
		auto atop(que.top());

		ld vel=-atop.first;
		int now=atop.second;
		que.pop();
		if(vels[now]>-0.5)continue;
		
		vels[now]=vel;
		
		if (now != 0) {
			que.push(make_pair(-getr(A,vel,straights[now-1]),now-1));
		}
		if (now != arcs.size() - 1) {
			que.push(make_pair(-getr(A,vel,straights[now]),now+1));
		}
	}

	ld answer=0;
	for (int i = 0; i < straights.size(); ++i) {
		answer+=get_time(A,vels[i],vels[i+1],straights[i]);
	}
	for (int i = 1; i < arcs.size()-1; ++i) {
		answer+=arcs[i].second/vels[i];
	}
	return answer;
}
int main()
{
	int N;cin>>N;
	ld A;cin>>A;
	vector<pair<pair<ld,ld>,pair<ld,ld>>>vs;
	vector<Line>ls;
	for (int i = 0; i < N; ++i) {
		int a,b,c,d;cin>>a>>b>>c>>d;
		ls.push_back(Line(Point(a,b),Point(c,d)));
	}

	//maxspeed , length
	vector<pair<ld, ld>>arcs(1, pair<ld, ld>{0, 0});;
	for (int i = 0; i < N - 1; i++) {
		Line l(ls[i]);
		Line r(ls[i+1].a,ls[i+1].b);
		//Line bis(line_bisection(l,r));

		ld theta(gettheta(r.b-r.a,l.b-l.a));

		if (theta < eps) {
			arcs.emplace_back(1e9,abs(r.a-l.b));
		}
		else {
			{
				if (ccw(l.a, l.b, r.a) == -1) {
					theta=theta;
				}
				else {
					theta=2*pi-theta;
				}
			}
			ld radius=abs(theta-pi)<eps?1*abs(r.a-l.b)/2:abs(r.a-l.b)*(sin((pi-theta)/2)/sin(theta));

			ld len=radius*theta;
			ld max_speed=sqrt(radius*A);
			arcs.emplace_back(max_speed,len);
		}
	}
	arcs.push_back(make_pair(0,0));
	vector<ld>straights;
	for (int i = 0; i < N; ++i) {
		straights.push_back(abs(ls[i].b-ls[i].a));
	}
	ld ans=solve(A,straights,arcs);
	cout<<setprecision(10)<<fixed<<ans<<endl;
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 16672
final_rank: 15

code_snippet: #ifndef VS
#include<iostream>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<iomanip>
#include<string>
#include<assert.h>
#include<math.h>
#include<stdio.h>
#include<ctype.h>
#include<complex>
#endif
using namespace std;
typedef long long LL;

#ifdef BTK
#define DEBUG if(1)
#else
#define DEBUG if(0)
#endif

#define FOR(i,bg,ed) for(int i=(bg);i<(ed);i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
#define REC(ret, ...) std::function<ret (__VA_ARGS__)>
template <typename T>inline bool chmin(T &l, T r) { bool a = l>r; if (a)l = r; return a; }
template <typename T>inline bool chmax(T &l, T r) { bool a = l<r; if (a)l = r; return a; }

struct input {
	bool success;
	input(){success = true;}
#ifdef BTK
	template<typename T>inline input& operator>>(T& x) {success = !!(cin >> x);return *this;}
#else
	inline input& operator>>(LL& x) {success = (scanf("%lld", &x) != EOF);return *this;}
	inline input& operator>>(int& x) {success = (scanf("%d", &x) != EOF);return *this;}
	inline input& operator>>(char* x) {success = (scanf("%s", x) != EOF);return *this;}
	inline input& operator>>(double& x) {success = (scanf("%lf", &x) != EOF);return *this;}
#endif
}in;

const char space = ' ';
const char ln = '\n';
struct output {
#ifdef BTK
	template<typename T>inline output& operator<<(T x) {cout << x; return (*this);}
	inline void fp(const double x, const char* s) { char buf[20];sprintf(buf, s, x); cout << buf;}
#else
	inline output& operator<<(const string& x) { printf("%s", x.c_str()); return *this; }
	inline output& operator<<(const int x) { printf("%d", x); return *this;}
	inline output& operator<<(const char x) { putchar(x); return *this;}
	inline output& operator<<(const LL x) { printf("%lld", x); return *this;}
	inline output& operator<<(const double x) { printf("%lf", x); return *this;}
	inline void fp(const double x, const char* s) {printf(s, x);}
#endif
}out;

#define fi first
#define se second
#define pb push_back

#define IL inline 
namespace geo {
	typedef double D;
	typedef bool B;
	typedef complex<D> P;
#define X real()
#define Y imag()
	B comp(const P& l, const P& r) { return (l.X == r.X) ? l.Y < r.Y : l.X < r.X; }
	typedef pair<P, P> L;  //line
	typedef pair<P, P> LS; //line segment
	typedef pair<P, D> C;  //circle
	typedef vector<P> Poly;
	const D EPS = 1e-8;
	//Decompotision Macro
#define DCl(a,b,l) P (a)=l.fi,(b)=l.se; 
#define DCc(a,b,c) P (a)=c.fi;D (b)=c.se; 

	//A dot B
	IL D dot(P a, P b) { return a.X*b.X + a.Y*b.Y; }
	//A cross B
	IL D cross(P a, P b) { return a.X*b.Y - a.Y*b.X; }
	IL D ccw(P a, P b, P c) {
		return cross(b - a, c - a);
	}

	IL int sgn(P a, P b, P c) {
		if (cross(b - a, c - a) > EPS)return 1;
		if (cross(b - a, c - a) < -EPS)return -1;
		if (dot(b - a, c - a) < -EPS)return 2; // b-a-c
		if (dot(a - b, c - b) < -EPS)return -2; // a-b-c
		return 0;
	}
	IL B is_L_L(L p, L q) {
		DCl(a, b, p);
		DCl(c, d, q);
		return
			abs(cross(a - b, c - d)) > EPS 
			//|| abs(cross(a - b, d - b)) < EPS
			;

	}
	IL D signed_distance_P_L(P p, L l) {
		DCl(a, b, l);
		return ccw(a, b, p) / abs(b - a);
	}

	IL P cross_L_L(L p, L q) {
		DCl(a, b, p);
		D d1 = signed_distance_P_L(a, q);
		D d2 = signed_distance_P_L(b, q);
		return (a * d2 - b * d1) / (d2 - d1);
	}

}
using namespace geo;
const D pi = acos(-1);
int main() {
	int N;
	in >> N;
	D amax;
	in >> amax;
	vector<LS> ls(N);
	vector<P> center(N - 1);
	vector<D> vmax(N + 1);
	REP(i, N) {
		D a, b, c, d;
		in >> a >> b >> c >> d;
		ls[i]=LS(P(a, b), P(c, d));
	}
	vmax[0] = 0;
	REP(i, N - 1) {
		LS prv = ls[i];
		LS nxt = ls[i+1];
		P v = prv.second - prv.first;
		P u = nxt.second - nxt.first;
		v = P(-v.Y, v.X);
		u = P(-u.Y, u.X);
		prv = LS(prv.second, prv.second + v);
		nxt = LS(nxt.first, nxt.first + u);
		if (is_L_L(prv, nxt)) {
			center[i] = cross_L_L(prv, nxt);
		}
		else {
			center[i] = (prv.first + nxt.first) / 2.0;
		}
		D r = abs(prv.first - center[i]);
		vmax[i + 1] = amax*r;
	}
	vmax[N] = 0;
	REP(i, N) {
		D s = abs(ls[i].second - ls[i].first);
		chmin(vmax[i + 1], vmax[i] + 2 * amax*s);
	}
	D ret = 0;
	REP(_, N) {
		int i = N - _ - 1;
		D s = abs(ls[i].second - ls[i].first);
		chmin(vmax[i], vmax[i + 1] + 2 * amax*s);
	}
	REP(i, N - 1) {
		P v = ls[i].second - center[i];
		P u = ls[i+1].first - center[i];
		D r = abs(v);
		D si = cross(v, u);
		D co = dot(v, u);
		D theta = atan2(si, co);
		if (theta < 0)theta =-theta;
		if (abs(theta - pi)>EPS) {
			P cp = cross_L_L(ls[i], ls[i + 1]);
			if (dot(cp - ls[i].second, ls[i].second - ls[i].first) < 0) {
				theta = 2 * pi - theta;
			}
		}
		D s = r*theta;
		ret += s / sqrt(vmax[i + 1]);
	}
	REP(i, N) {
		/*
		v1-v0 = 2*a*s
		w = v0+2*a*x;
		w = v1+2*a*y;
		v1-v0 = 2*a*(x-y)

		*/
		D s = abs(ls[i].second - ls[i].first);
		D x = (s + (vmax[i + 1] - vmax[i]) / (2.0*amax)) / 2.0;
		D y = s - x;
		D w = sqrt(vmax[i] + 2 * amax*x);
		D ww = sqrt(vmax[i + 1] + 2 * amax*y);
		//t*(v+u)/2 = x
		ret += 2.0*x / (sqrt(vmax[i]) + w);
		ret += 2.0*y / (sqrt(vmax[i + 1]) + w);
	}
	out.fp(ret, "%.10f\n");
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 4980
final_rank: 3

code_snippet: #include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
int x1[41000];
int Y1[41000];
int x2[41000];
int y2[41000];
double r[41000];
double len[41000];
const double EPS = 1e-10;
const double INF = 1e+10;
const double PI = acos(-1);
int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }
inline double ABS(double a){return max(a,-a);}
struct Pt {
	double x, y;
	Pt() {}
	Pt(double x, double y) : x(x), y(y) {}
	Pt operator+(const Pt &a) const { return Pt(x + a.x, y + a.y); }
	Pt operator-(const Pt &a) const { return Pt(x - a.x, y - a.y); }
	Pt operator*(const Pt &a) const { return Pt(x * a.x - y * a.y, x * a.y + y * a.x); }
	Pt operator-() const { return Pt(-x, -y); }
	Pt operator*(const double &k) const { return Pt(x * k, y * k); }
	Pt operator/(const double &k) const { return Pt(x / k, y / k); }
	double ABS() const { return sqrt(x * x + y * y); }
	double abs2() const { return x * x + y * y; }
	double arg() const { return atan2(y, x); }
	double dot(const Pt &a) const { return x * a.x + y * a.y; }
	double det(const Pt &a) const { return x * a.y - y * a.x; }
};
double tri(const Pt &a, const Pt &b, const Pt &c) { return (b - a).det(c - a); }
Pt p1[41000];
Pt p2[41000];
int iLL(Pt a, Pt b, Pt c, Pt d) {
	if (sig((b - a).det(d - c))) return 1; // intersect
	if (sig((b - a).det(c - a))) return 0; // parallel
	return -1; // correspond
}
Pt pLL(Pt a, Pt b, Pt c, Pt d) {
	b = b - a; d = d - c; return a + b * (c - a).det(d) / b.det(d);
}
double v[41000];
double gett(double a,double s,double v1,double v2){
	double vt=sqrt(a*s+(v1*v1+v2*v2)/2);
	//printf("%f %f\n",vt,(2*vt-v1-v2)/a);
	return (2*vt-v1-v2)/a;
}
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	for(int i=0;i<a;i++){
		scanf("%d%d%d%d",x1+i,Y1+i,x2+i,y2+i);
		p1[i]=Pt((double)x1[i],(double)Y1[i]);
		p2[i]=Pt((double)x2[i],(double)y2[i]);
	}
	for(int i=0;i<a-1;i++){
		if(iLL(p1[i],p2[i],p1[i+1],p2[i+1])==0){
			double d=(p2[i]-p1[i+1]).ABS();
			r[i]=d/2;
			len[i]=d*PI/2;
		}else{
			Pt p=pLL(p2[i],p2[i]+(p1[i]-p2[i])*Pt(0,1),p1[i+1],p1[i+1]+(p2[i+1]-p1[i+1])*Pt(0,1));
			r[i]=(p-p2[i]).ABS();
			double d=(p2[i]-p1[i+1]).ABS()/2;
			double th=asin(d/r[i])*2;
			if((p2[i]-p1[i]).dot(p1[i+1]-p2[i])<-EPS)th+=PI;
			len[i]=r[i]*th;
		}
	}
	double now=0;
	for(int i=0;i<a-1;i++){
		now=sqrt((p2[i]-p1[i]).ABS()*2*b+now*now);
		now=min(now,sqrt(r[i]*b));
		v[i+1]=now;
	}
	now=0;
	for(int i=a-1;i>0;i--){
		now=sqrt((p2[i]-p1[i]).ABS()*2*b+now*now);
		now=min(now,sqrt(r[i-1]*b));
		now=min(now,v[i]);
		v[i]=now;
	}
	//for(int i=0;i<=a;i++)printf("%f %f %f\n",v[i],r[i],len[i]);
	double ret=0;
	for(int i=0;i<a;i++){
		ret+=gett((double)b,(p2[i]-p1[i]).ABS(),v[i],v[i+1]);
		if(i<a-1){
			ret+=len[i]/v[i+1];
		}
	}
	printf("%.10f\n",ret);
}
accuracy: 1
time_ms: 20
memory_kb: 3908
final_rank: 1

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <iomanip>

using namespace std;

const int N = 40000 + 10;
const double eps = 1e-8;
const double PI = acos(-1.0);

int sgn(double x)
{
	if (x < -eps) return -1;
	if (x > eps) return 1;
	return 0;
}

double dbl(double x)
{
	return x * x;
}

struct Point {
	double x, y;
	Point() {}
	Point(const double _x, const double _y) {
		x = _x, y = _y;
	}
	friend Point operator + (const Point &a, const Point &b) {
		return Point(a.x + b.x, a.y + b.y);
	}
	friend Point operator - (const Point &a, const Point &b) {
		return Point(a.x - b.x, a.y - b.y);
	}
	friend Point operator * (const Point &a, const double k) {
		return Point(a.x * k, a.y * k);
	}
	friend Point operator / (const Point &a, const double k) {
		return Point(a.x / k, a.y / k);
	}
	friend double dot(const Point &a, const Point &b) {
		return (a.x * b.x + a.y * b.y);
	}
	friend double det(const Point &a, const Point &b) {
		return (a.x * b.y - a.y * b.x);
	}
	friend double len(const Point &a) {
		return sqrt(a.x * a.x + a.y * a.y);
	}
	void read() {
		cin >> x >> y;
	}
	void write() const {
		cout << x << " " << y << endl;
	}
};

struct Seg {
	Point u, v, w;
	double dist;
	Seg() {}
	Seg(const Point &_u, const Point &_v) {
		u = _u, v = _v;
	}
	void read() {
		u.read();
		v.read();
	}
	void prepare() {
		w = v - u;
		w = Point(-w.y, w.x);
		dist = len(v - u);
	}
} seg[N];

bool intersect(const Point &a, const Point &b, const Point &c, const Point &d, Point &e)
{
	double s1 = det(c - a, d - a);
	double s2 = det(d - b, c - b);
	if (!sgn(s1 + s2)) return false;
	e = (b - a) * (s1 / (s1 + s2)) + a;
	return true;
}

double rectify(double x)
{
	while (x < -eps) x += 2 * PI;
	while (x > 2 * PI + eps) x -= 2 * PI;
	return x;
}

int n;
Point center[N];
double amax, radius[N], angle[N], vmax[N][2];

double calc(double vstart, double vend, double dist)
{
	double vm = sqrt((2 * amax * dist + dbl(vstart) + dbl(vend)) / 2.0);
	double ret = (2 * vm - vstart - vend) / amax;
	return ret;
}

int main()
{
	ios::sync_with_stdio(false);
	cin >> n >> amax;
	for (int i = 1; i <= n; ++i) {
		seg[i].read();
		seg[i].prepare();
	}
	for (int i = 1; i < n; ++i) {
		static Point u, v;
		static double ang1, ang2;
		
		bool ret = intersect(seg[i].v, seg[i].v + seg[i].w, seg[i + 1].u, seg[i + 1].u + seg[i + 1].w, center[i]);
		if (!ret) center[i] = (seg[i].v + seg[i + 1].u) / 2.0;

		radius[i] = len(seg[i].v - center[i]);
		u = seg[i].v - center[i];
		v = seg[i + 1].u - center[i];
		ang1 = atan2(u.y, u.x);
		ang2 = atan2(v.y, v.x);
		if (sgn(det(seg[i].v - center[i], seg[i].v - seg[i].u)) > 0) {
			angle[i] = rectify(ang2 - ang1);
		} else {
			angle[i] = rectify(ang1 - ang2);
		}
	}
	/*
	for (int i = 1; i < n; ++i) {
		cout << center[i].x << " " << center[i].y << " " << angle[i] << endl;
	}
	*/
	vmax[n][1] = 0.0;
	vmax[n][0] = sqrt(2 * amax * seg[n].dist);
	
	for (int i = n - 1; i >= 1; --i) {
		vmax[i][1] = min(vmax[i + 1][0], sqrt(amax * radius[i]));
		vmax[i][0] = sqrt(dbl(vmax[i][1]) + 2 * amax * seg[i].dist);
	}

	double times = 0;
	double v = 0;

	for (int i = 1; i <= n; ++i) {
		if (v > vmax[i][1]) {
			times += calc(v, vmax[i][1], seg[i].dist);
			v = vmax[i][1];
		} else {
			if (dbl(v) + 2 * amax * seg[i].dist <= dbl(vmax[i][1])) {
				times += (sqrt(dbl(v) + 2 * amax * seg[i].dist) - v) / amax;
				v = sqrt(dbl(v) + 2 * amax * seg[i].dist);
			} else {
				times += calc(v, vmax[i][1], seg[i].dist);
				v = vmax[i][1];
			}
		}
		if (i < n) {
			times += radius[i] * angle[i] / v;
		}
	}

	cout << setiosflags(ios::fixed) << setprecision(8) << times << endl;
	
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 5384
final_rank: 6

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <iomanip>

using namespace std;

const int N = 40000 + 10;
const double eps = 1e-8;
const double PI = acos(-1.0);

int sgn(double x)
{
	if (x < -eps) return -1;
	if (x > eps) return 1;
	return 0;
}

double dbl(double x)
{
	return x * x;
}

struct Point {
	double x, y;
	Point() {}
	Point(const double _x, const double _y) {
		x = _x, y = _y;
	}
	friend Point operator + (const Point &a, const Point &b) {
		return Point(a.x + b.x, a.y + b.y);
	}
	friend Point operator - (const Point &a, const Point &b) {
		return Point(a.x - b.x, a.y - b.y);
	}
	friend Point operator * (const Point &a, const double k) {
		return Point(a.x * k, a.y * k);
	}
	friend Point operator / (const Point &a, const double k) {
		return Point(a.x / k, a.y / k);
	}
	friend double dot(const Point &a, const Point &b) {
		return (a.x * b.x + a.y * b.y);
	}
	friend double det(const Point &a, const Point &b) {
		return (a.x * b.y - a.y * b.x);
	}
	friend double len(const Point &a) {
		return sqrt(a.x * a.x + a.y * a.y);
	}
	void read() {
		cin >> x >> y;
	}
	void write() const {
		cout << x << " " << y << endl;
	}
};

struct Seg {
	Point u, v, w;
	double dist;
	Seg() {}
	Seg(const Point &_u, const Point &_v) {
		u = _u, v = _v;
	}
	void read() {
		u.read();
		v.read();
	}
	void prepare() {
		w = v - u;
		w = Point(-w.y, w.x);
		dist = len(v - u);
	}
} seg[N];

bool intersect(const Point &a, const Point &b, const Point &c, const Point &d, Point &e)
{
	double s1 = det(c - a, d - a);
	double s2 = det(d - b, c - b);
	if (!sgn(s1 + s2)) return false;
	e = (b - a) * (s1 / (s1 + s2)) + a;
	return true;
}

double rectify(double x)
{
	while (x < -eps) x += 2 * PI;
	while (x > 2 * PI + eps) x -= 2 * PI;
	return x;
}

int n;
Point center[N];
double amax, radius[N], angle[N], vmax[N][2];

double calc(double vstart, double vend, double dist)
{
	double vm = sqrt((2 * amax * dist + dbl(vstart) + dbl(vend)) / 2.0);
	double ret = (2 * vm - vstart - vend) / amax;
	return ret;
}

int main()
{
	ios::sync_with_stdio(false);
	cin >> n >> amax;
	for (int i = 1; i <= n; ++i) {
		seg[i].read();
		seg[i].prepare();
	}
	for (int i = 1; i < n; ++i) {
		static Point u, v;
		static double ang1, ang2;
		
		bool ret = intersect(seg[i].v, seg[i].v + seg[i].w, seg[i + 1].u, seg[i + 1].u + seg[i + 1].w, center[i]);
		if (!ret) center[i] = (seg[i].v + seg[i + 1].u) / 2.0;

		radius[i] = len(seg[i].v - center[i]);
		u = seg[i].v - center[i];
		v = seg[i + 1].u - center[i];
		ang1 = atan2(u.y, u.x);
		ang2 = atan2(v.y, v.x);
		if (sgn(det(seg[i].v - center[i], seg[i].v - seg[i].u)) > 0) {
			angle[i] = rectify(ang2 - ang1);
		} else {
			angle[i] = rectify(ang1 - ang2);
		}
	}
	/*
	for (int i = 1; i < n; ++i) {
		cout << center[i].x << " " << center[i].y << " " << angle[i] << endl;
	}
	*/
	vmax[n][1] = 0.0;
	vmax[n][0] = sqrt(2 * amax * seg[n].dist);
	
	for (int i = n - 1; i >= 1; --i) {
		vmax[i][1] = min(vmax[i + 1][0], sqrt(amax * radius[i]));
		vmax[i][0] = sqrt(dbl(vmax[i + 1][1]) + 2 * amax * seg[i].dist);
	}

	double times = 0;
	double v = 0;

	for (int i = 1; i <= n; ++i) {
		if (v > vmax[i][1]) {
			times += calc(v, vmax[i][1], seg[i].dist);
			v = vmax[i][1];
		} else {
			if (dbl(v) + 2 * amax * seg[i].dist <= dbl(vmax[i][1])) {
				times += (sqrt(dbl(v) + 2 * amax * seg[i].dist) - v) / amax;
				v = sqrt(dbl(v) + 2 * amax * seg[i].dist);
			} else {
				times += calc(v, vmax[i][1], seg[i].dist);
				v = vmax[i][1];
			}
		}
		if (i < n) {
			times += radius[i] * angle[i] / v;
		}
	}

	cout << setiosflags(ios::fixed) << setprecision(8) << times << endl;
	
	return 0;
}
accuracy: 0.96
time_ms: 30
memory_kb: 5388
final_rank: 19

code_snippet: #include <cstdio>
#include <algorithm>
#include <cmath>

const double PI = acos(-1.);
const double eps = 1e-8;

__inline int sgn(const double &x, const double &eps = 1e-8) {
    return (x < -eps) ? -1 : (x > eps);
}

class Point {
public:
    double x, y;

    Point() {}

    Point(const double &x, const double &y) : x(x), y(y) {}
	
	void read() {
		scanf("%lf%lf", &x, &y);
	}
	
	double len() const {
		return sqrt(x * x + y * y);
	}
	
	Point norm() {
		return Point(x / len(), y / len());
	}

    friend Point operator + (const Point &a, const Point &b) {
        return Point(a.x + b.x, a.y + b.y);
    }

    friend Point operator - (const Point &a, const Point &b) {
        return Point(a.x - b.x, a.y - b.y);
    }

    friend Point operator * (const Point &a, const double &k) {
        return Point(a.x * k, a.y * k);
    }

    friend Point operator * (const double &k, const Point &a) {
        return Point(a.x * k, a.y * k);
    }

    friend Point operator / (const Point &a, const double &k) {
        return Point(a.x / k, a.y / k);
    }

    friend bool operator == (const Point &a, const Point &b) {
        return sgn(a.x - b.x) == 0 && sgn(a.y - b.y) == 0;
    }

    friend bool operator < (const Point &a, const Point &b) {
        if (sgn(a.x - b.x) == 0) {
            return sgn(a.y - b.y) < 0;
        } else {
            return sgn(a.x - b.x) < 0;
        }
    }

    friend double det(const Point &a, const Point &b) {
        return a.x * b.y - a.y * b.x;
    }

    friend double det(const Point &a, const Point &b, const Point &c) {
        return det(b - a, c - a);
    }

    friend double dot(const Point &a, const Point &b) {
        return a.x * b.x + a.y * b.y;
    }
	
    friend double dot(const Point &a, const Point &b, const Point &c) {
        return dot(b - a, c - a);
    }

	friend double dist(const Point &a, const Point &b) {
		return (a - b).len();
	}	
	
    friend bool check(const Point &a, const Point &b, const Point &c, const Point &d) {
        double s1 = det(a, b, c);
        double s2 = det(a, b, d);
        return sgn(s1 - s2) != 0;
    }
	
    friend Point intersect(const Point &a, const Point &b, const Point &c, const Point &d) {
        double s1 = det(a, b, c);
        double s2 = det(a, b, d);
        return (s1 * d - s2 * c) / (s1 - s2);
    }
};

bool point_on_line(const Point &p, const Point &a, const Point &b) {
    return sgn(det(p, a, b)) == 0 && sgn(dot(p, a, b)) <= 0;
}

const int N = 44444;

int n;
double amax;
Point a[N], b[N];
double pdist[N], radius[N], angle[N], vmax[N][2];

__inline double fix(double x) {
	for (; x < -eps; x += 2 * PI);
	for (; x > 2 * PI - eps; x -= 2 * PI);
	return x;
}

__inline std::pair<Point, Point> vertical(const Point &a, const Point &b) {
	Point vec = b - a;
	Point per = Point(-vec.y, vec.x);
	return std::make_pair(a, a + per);
}
int check(double mid, double v0, double v, double d) {
	double dist = v0 * mid + amax * mid * mid / 2;
	if (dist > d) return 0;
	if (v0 + mid * amax < v) return 1; 
	double need = (v0 + mid * amax - v) / amax;
	double nowv = v0 + mid * amax;
	if (nowv * need - .5 * need * need * amax + dist > d) return 0;
	return 1;
}

double get(double v0, double v, double d) {
	double l = 0, r = sqrt(2 * d / amax) + 100;
	int counter = 40;
	while (counter--) {
		double mid = (l + r) / 2;
		if (check(mid, v0, v, d)) l = mid;
		else r = mid;
	}
	
	double ret = (l + r) / 2;
	ret += (v0 + (l + r) / 2 * amax - v) / amax;
	return ret;
}

int main(void) {
	scanf("%d%lf", &n, &amax);
	for (int i = 0; i < n; ++i) {
		a[i].read();
		b[i].read();
		pdist[i] = dist(a[i], b[i]);
	}
	
	for (int i = 0; i < n - 1; ++i) {
		std::pair<Point, Point> pair1 = vertical(b[i], a[i]);
		std::pair<Point, Point> pair2 = vertical(a[i + 1], b[i + 1]);
		
		Point o;
		if (!check(pair1.first, pair1.second, pair2.first, pair2.second)) {
			o = (b[i] + a[i + 1]) / 2;
		} else {
			o = intersect(pair1.first, pair1.second, pair2.first, pair2.second);
		}
		radius[i] = dist(o, b[i]);
		
		double angle1 = atan2(b[i].y - o.y, b[i].x - o.x);
		double angle2 = atan2(a[i + 1].y - o.y, a[i + 1].x - o.x);
		
		if (sgn(det(b[i] - o, b[i] - a[i])) > 0) {
			angle[i] = fix(angle2 - angle1);
		} else {
			angle[i] = fix(angle1 - angle2);
		}
	}
	
	vmax[n - 1][0] = sqrt(2 * amax * pdist[n - 1]);
	vmax[n - 1][1] = 0;
	
	for (int i = n - 2; i >= 0; --i) {
		vmax[i][1] = std::min(sqrt(radius[i] * amax), vmax[i + 1][0]);
		vmax[i][0] = sqrt(vmax[i][1] * vmax[i][1] + 2 * amax * pdist[i]);
	}

	double nowv = 0;
	double ans = 0;
	
	for (int i = 0; i < n; i++) {
		if (nowv > vmax[i][1]) {
			double tmp = get(nowv, vmax[i][1], pdist[i]);
			ans += tmp;
			nowv = vmax[i][1];
		}
		else {	
			if (nowv * nowv + 2 * amax * pdist[i] < vmax[i][1] * vmax[i][1]) {
				double tmp = sqrt(nowv * nowv + 2 * amax * pdist[i]);
				ans += (tmp - nowv) / amax;
				nowv = tmp;
			} else {
				double tmp = get(nowv, vmax[i][1], pdist[i]);
	
				ans += tmp;
				nowv = vmax[i][1];
			}
		}
		if (i < n - 1) {
			ans += radius[i] * angle[i] / nowv;
		}		
	}
	
	printf("%0.9f\n", ans);
}
accuracy: 1
time_ms: 50
memory_kb: 3944
final_rank: 10

code_snippet: #include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

const double eps = 1e-9;
const double inf = 9999999.0;

const double pi = acos(-1.0);
struct point
{
	double x, y;
	point() {}
	point(double x, double y) : x(x), y(y) {}
};

point operator + (const point& p1, const point& p2) { return point(p1.x + p2.x, p1.y + p2.y); }
point operator - (const point& p1, const point& p2) { return point(p1.x - p2.x, p1.y - p2.y); }
point operator * (const point& p1, double d) { return point(p1.x * d, p1.y * d); }
point operator / (const point& p1, double d) { return point(p1.x / d, p1.y / d); }

double sqr(double x) { return x * x; }
double dist(point p1, point p2) { return sqrt(sqr(p1.x - p2.x) + sqr(p1.y - p2.y)); }
double dot(point p1, point p2) { return p1.x * p2.x + p1.y * p2.y; }
double det(point p1, point p2) { return p1.x * p2.y - p1.y * p2.x; }
int dcmp(double x) { return fabs(x) <= eps ? 0 : (x > 0 ? 1 : -1); }

point rot(point p) { return point(-p.y, p.x); }
point mid(point p, point q) { return (p + q) / 2.0; }
point inter(point p, point v, point q, point w)
{
	point u = p - q;
	double t = det(w, u) / det(v, w);
	return p + v * t;
}

double calc(double t, double v0, double v1, double a)
{
	double x = (v1 - v0 + a * t) / (2 * a);
	double vm = v0 + a * x;
	return (v0 + vm) * x / 2.0 + (vm + v1) * (t - x) / 2.0; 
}

double find(double v1, double v2, double L, double a)
{
	double l = fabs(v1 - v2) / a, r = inf;
	for (int i = 1; i <= 100; i ++)
	{
		double mid = (l + r) / 2.0;
		if (calc(mid, v1, v2, a) <= L) l = mid;
		else r = mid;
	}
	return l;
}

int n;
double amax;

point a[100001], b[100001];
double theta[100001], r[100001], l[100001];
double vr[100001];
double len[100001], rad[100001];
double ans = 0.0;

int main( )
{
	scanf("%d", &n);
	scanf("%lf", &amax);
	for (int i = 1; i <= n; i ++)
	{
		scanf("%lf %lf %lf %lf", &a[i].x, &a[i].y, &b[i].x, &b[i].y);
		len[i] = dist(a[i], b[i]);
	}
	for (int i = 1; i < n; i ++)
	{
		point tmpx = b[i], tmpy = a[i + 1];
		point p = mid(tmpx, tmpy), rev = rot(tmpy - tmpx);
		
		point o = inter(p, rev, b[i], rot(a[i] - b[i]));
		rad[i] = dist(b[i], o);
		tmpx = b[i] - a[i];
		tmpy = b[i + 1] - a[i + 1];
		theta[i] = atan2(tmpy.y, tmpy.x) - atan2(tmpx.y, tmpx.x);
		if (dcmp(theta[i]) < 0) theta[i] += 2 * pi;
		if (dcmp(det(b[i] - a[i], a[i + 1] - a[i])) < 0) theta[i] = 2.0 * pi - theta[i];
		double vmax = sqrt(amax * rad[i]);
		r[i] = vmax, l[i + 1] = vmax;
	}
	l[1] = 0, r[n] = 0;
	for (int i = n - 1; i >= 1; i --)
		r[i] = min(r[i], sqrt(2.0 * len[i + 1] * amax + sqr(r[i + 1])));
	for (int i = 2; i <= n; i ++)
		l[i] = sqrt(2.0 * len[i] * amax + sqr(r[i]));
	double now = 0.0; 
	for (int i = 1; i <= n; i ++)
	{
		ans += find(now, r[i], len[i], amax);
		now = min(sqrt(sqr(now) + 2.0 * len[i] * amax), r[i]);
		if (i != n) ans += theta[i] * rad[i] / now;
	}
	printf("%.9f\n", ans);
	return 0;
}
// a = sqr(v) / r;
// r[i] maxv enter the seg
// l[i]
accuracy: 1
time_ms: 100
memory_kb: 6468
final_rank: 14

code_snippet: #include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <iostream>
#include <cstring>

using namespace std;

const long double eps = 1e-8;
const long double pi = acos(-1.0);
const int maxn = 4e4 + 100;
long double am;
int n;
int dcmp(long double x){
	return x < -eps? -1 : x > eps;
}

long double sqr(long double x){
	return x * x;
}

struct point{
	long double x, y;
	point(long double x = 0, long double y = 0):x(x),y(y){}
	void read(){
		scanf("%Lf%Lf",&x,&y);
	}
	point operator + (const point &b){
		return point(x + b.x, y + b.y);
	}
	point operator - (const point &b){
		return point(x - b.x, y - b.y);
	}
	point operator * (long double a){
		return point(x * a, y * a);
	}
	point operator / (long double a){
		return point(x / a, y / a);
	}
	bool operator == (const point &b){
		return dcmp(x - b.x)==0 && dcmp(y - b.y)==0;
	}
	
};

point a[maxn],b[maxn];
point a1[maxn],b1[maxn];
long double arclen[maxn];
long double vmax[maxn],vc[maxn];
long double r[maxn];
long double angle[maxn];

long double dot(point a, point b){
	return a.x*b.x + a.y*b.y;
}
long double len2(point a){
	return dot(a,a);
}
long double len(point a){
	return sqrt(len2(a));
}
long double cross(point a, point b){
	return a.x*b.y - a.y*b.x;
}
point getlineinter(point p, point v, point q, point w){
	point u = p - q;
	long double t = cross(w,u) / cross(v,w);
	return p + v*t;
}
point rotate(point a){
	return point (-a.y, a.x);
}
bool rightside(point a1, point b1, point a2){
	point v1 = b1 - a1;
	point v2 = a2 - a1;
	if (cross(v2,v1) > 0)return 1;
	else return 0;
}
pair<long double, long double> gettime(long double len, long double v1, long double v2)
{
	if (dcmp(2*am*len + sqr(v1) - sqr(v2)) <= 0){
		long double v = sqrt(2*am*len + sqr(v1));
		long double t = (v - v1)/am;
		return make_pair(v,t);
	}
	if (dcmp(2*am*len + sqr(v2) - sqr(v1)) == 0)return make_pair(v2, (v1 - v2)/am);
	long double v = sqrt(am*len + (sqr(v1) + sqr(v2))/2);
	long double t = (2*v - v1 - v2)/am;
	//cout<<"@@"<<endl;
	return make_pair(v2,t);
}

void work(int i, int j)
{
	point v1 = rotate(b[i] - a[i]);
	point v2 = rotate(b[j] - a[j]);
	point c;
	if (dcmp(cross(v1,v2))==0){
		c = (b[i] + a[j])/2;
	}else{	
	c = getlineinter(b[i], v1, a[j], v2);
	}
	r[i] = len(c - b[i]);
	
	//cout<<r[i]<<endl;

	v1 = b[i] - a[i];
	v2 = b[j] - a[j];
	long double a2 = atan2(v2.y, v2.x);
	long double a1 = atan2(v1.y, v1.x);
	long double tmp = a2 - a1;
	if (tmp < 0)tmp += 2 * pi;
	if (rightside(a[i],b[i], a[j]))
		tmp = 2 * pi - tmp;
	angle[i] = tmp;
	//r[i] = fabs(len(b[i] - a[j])/2/sin(angle[i]/2));
	vc[i] = sqrt(am * r[i]);
	
	
}
long double gettime2(long double v, long double angle, long double r)
{
	return (r * angle)/v;	
}

int main()
{
	scanf("%d%Lf",&n,&am);
	for (int i = 0; i < n; ++i)
	{
		a1[i].read();
		b1[i].read();
	}
	int rear = 1;
	a[0] = a1[0];
	b[0] = b1[0];	
	for (int i = 1; i < n; ++i)
	if(b[rear] == a1[i]){
		b[rear] = b1[i];
	}else{
		a[rear] = a1[i];
		b[rear++] = b1[i];
	}
	n = rear;
	
	for (int i = 0; i < n-1; ++i)
	{
		work(i,i+1);
	}	
	vmax[n-1] = 0;
	for (int i = n - 2; i >= 0; --i)
	{
		vmax[i] = min(vc[i], sqrt(2 * am * len(b[i+1] - a[i+1]) + sqr(vmax[i+1])));	
		//cout<<i<<":"<<vmax[i]<<endl;	
	}
	long double ans = 0;
	long double cur = 0;
	for (int i = 0; i < n; ++i)
	{
		//
		pair<long double, long double> tmp = gettime(len(b[i] - a[i]), cur, vmax[i]);
		cur = tmp.first;
		//cout<<"cur:"<<cur<<endl;
		ans += tmp.second;
		//cout<<tmp.second<<endl;
		if (i != n-1){
			long double ttt = gettime2(cur, angle[i],r[i]);
			//cout<<"time2:"<<ttt<<endl;
			//cout<<"angle:"<<angle[i]<<endl;
			ans += gettime2(cur, angle[i],r[i]);
		}		
		//cout<<"###"<<ans<<endl;
	}
	printf("%.12Lf\n",ans);
	
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 9408
final_rank: 12

code_snippet: #include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <iostream>
#include <cstring>

using namespace std;

const double eps = 1e-11;
const double pi = acos(-1.0);
const int maxn = 4e4 + 100;
double am;
int n;
int dcmp(double x){
	return x < -eps? -1 : x > eps;
}

double sqr(double x){
	return x * x;
}

struct point{
	double x, y;
	point(double x = 0, double y = 0):x(x),y(y){}
	void read(){
		scanf("%lf%lf",&x,&y);
	}
	point operator + (const point &b){
		return point(x + b.x, y + b.y);
	}
	point operator - (const point &b){
		return point(x - b.x, y - b.y);
	}
	point operator * (double a){
		return point(x * a, y * a);
	}
	point operator / (double a){
		return point(x / a, y / a);
	}
	bool operator == (const point &b){
		return dcmp(x - b.x)==0 && dcmp(y - b.y)==0;
	}
	
};

point a[maxn],b[maxn];
point a1[maxn],b1[maxn];
double arclen[maxn];
double vmax[maxn],vc[maxn];
double r[maxn];
double angle[maxn];

double dot(point a, point b){
	return a.x*b.x + a.y*b.y;
}
double len2(point a){
	return dot(a,a);
}
double len(point a){
	return sqrt(len2(a));
}
double cross(point a, point b){
	return a.x*b.y - a.y*b.x;
}
point getlineinter(point p, point v, point q, point w){
	point u = p - q;
	double t = cross(w,u) / cross(v,w);
	return p + v*t;
}
point rotate(point a){
	return point (-a.y, a.x);
}
bool rightside(point a1, point b1, point a2){
	point v1 = b1 - a1;
	point v2 = a2 - a1;
	if (cross(v2,v1) > 0)return 1;
	else return 0;
}
pair<double, double> gettime(double len, double v1, double v2)
{
	if (dcmp(2*am*len + sqr(v1) - sqr(v2)) <= 0){
		double v = sqrt(2*am*len + sqr(v1));
		double t = (v - v1)/am;
		return make_pair(v,t);
	}
	if (dcmp(2*am*len + sqr(v2) - sqr(v1)) == 0)return make_pair((v2 - v1)/am, v2);
	double v = sqrt(am*len + (sqr(v1) + sqr(v2))/2);
	double t = (2*v - v1 - v2)/am;
	//cout<<"@@"<<endl;
	return make_pair(v2,t);
}

void work(int i, int j)
{
	point v1 = rotate(b[i] - a[i]);
	point v2 = rotate(b[j] - a[j]);
	point c;
	if (dcmp(cross(v1,v2))==0){
		c = (b[i] + a[j])/2;
	}else{	
	c = getlineinter(b[i], v1, a[j], v2);
	}
	r[i] = len(c - b[i]);
	
	//cout<<r[i]<<endl;

	v1 = b[i] - a[i];
	v2 = b[j] - a[j];
	double a2 = atan2(v2.y, v2.x);
	double a1 = atan2(v1.y, v1.x);
	double tmp = a2 - a1;
	if (tmp < 0)tmp += 2 * pi;
	if (rightside(a[i],b[i], a[j]))
		tmp = 2 * pi - tmp;
	angle[i] = tmp;
	r[i] = fabs(len(b[i] - a[j])/2/sin(angle[i]/2));
	vc[i] = sqrt(am * r[i]);
	
	
}
double gettime2(double v, double angle, double r)
{
	return (r * angle)/v;	
}

int main()
{
	scanf("%d%lf",&n,&am);
	for (int i = 0; i < n; ++i)
	{
		a1[i].read();
		b1[i].read();
	}
	int rear = 1;
	a[0] = a1[0];
	b[0] = b1[0];	
	for (int i = 1; i < n; ++i)
	if(b[rear] == a1[i]){
		b[rear] = b1[i];
	}else{
		a[rear] = a1[i];
		b[rear++] = b1[i];
	}
	n = rear;
	
	for (int i = 0; i < n-1; ++i)
	{
		work(i,i+1);
	}	
	vmax[n-1] = 0;
	for (int i = n - 2; i >= 0; --i)
	{
		vmax[i] = min(vc[i], sqrt(2 * am * len(b[i+1] - a[i+1]) + sqr(vmax[i+1])));	
		//cout<<i<<":"<<vmax[i]<<endl;	
	}
	double ans = 0;
	double cur = 0;
	for (int i = 0; i < n; ++i)
	{
		//
		pair<double, double> tmp = gettime(len(b[i] - a[i]), cur, vmax[i]);
		cur = tmp.first;
		//cout<<"cur:"<<cur<<endl;
		ans += tmp.second;
		//cout<<tmp.second<<endl;
		if (i != n-1){
			double ttt = gettime2(cur, angle[i],r[i]);
			//cout<<"time2:"<<ttt<<endl;
			//cout<<"angle:"<<angle[i]<<endl;
			ans += gettime2(cur, angle[i],r[i]);
		}		
		//cout<<"###"<<ans<<endl;
	}
	printf("%.12f\n",ans);
	
	return 0;
}
accuracy: 0.96
time_ms: 20
memory_kb: 5044
final_rank: 18

code_snippet: #include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <iostream>
#include <cstring>

using namespace std;

const double eps = 1e-11;
const double pi = acos(-1.0);
const int maxn = 4e4 + 100;
double am;
int n;
int dcmp(double x){
	return x < -eps? -1 : x > eps;
}

double sqr(double x){
	return x * x;
}

struct point{
	double x, y;
	point(double x = 0, double y = 0):x(x),y(y){}
	void read(){
		scanf("%lf%lf",&x,&y);
	}
	point operator + (const point &b){
		return point(x + b.x, y + b.y);
	}
	point operator - (const point &b){
		return point(x - b.x, y - b.y);
	}
	point operator * (double a){
		return point(x * a, y * a);
	}
	point operator / (double a){
		return point(x / a, y / a);
	}
	bool operator == (const point &b){
		return dcmp(x - b.x)==0 && dcmp(y - b.y)==0;
	}
	
};

point a[maxn],b[maxn];
point a1[maxn],b1[maxn];
double arclen[maxn];
double vmax[maxn],vc[maxn];
double r[maxn];
double angle[maxn];

double dot(point a, point b){
	return a.x*b.x + a.y*b.y;
}
double len2(point a){
	return dot(a,a);
}
double len(point a){
	return sqrt(len2(a));
}
double cross(point a, point b){
	return a.x*b.y - a.y*b.x;
}
point getlineinter(point p, point v, point q, point w){
	point u = p - q;
	double t = cross(w,u) / cross(v,w);
	return p + v*t;
}
point rotate(point a){
	return point (-a.y, a.x);
}
bool rightside(point a1, point b1, point a2){
	point v1 = b1 - a1;
	point v2 = a2 - a1;
	if (cross(v2,v1) > 0)return 1;
	else return 0;
}
pair<double, double> gettime(double len, double v1, double v2)
{
	if (dcmp(2*am*len + sqr(v1) - sqr(v2)) <= 0){
		double v = sqrt(2*am*len + sqr(v1));
		double t = (v - v1)/am;
		return make_pair(v,t);
	}
	if (dcmp(2*am*len + sqr(v2) - sqr(v1)) == 0)return make_pair((v2 - v1)/am, v2);
	double v = sqrt(am*len + (sqr(v1) + sqr(v2))/2);
	double t = (2*v - v1 - v2)/am;
	//cout<<"@@"<<endl;
	return make_pair(v2,t);
}

void work(int i, int j)
{
	point v1 = rotate(b[i] - a[i]);
	point v2 = rotate(b[j] - a[j]);
	point c;
	if (dcmp(cross(v1,v2))==0){
		c = (b[i] + a[j])/2;
	}else{	
	c = getlineinter(b[i], v1, a[j], v2);
	}
	r[i] = len(c - b[i]);
	
	//cout<<r[i]<<endl;
	vc[i] = sqrt(am * r[i]);
	v1 = b[i] - a[i];
	v2 = b[j] - a[j];
	double a2 = atan2(v2.y, v2.x);
	double a1 = atan2(v1.y, v1.x);
	double tmp = a2 - a1;
	if (tmp < 0)tmp += 2 * pi;
	if (rightside(a[i],b[i], a[j]))
		tmp = 2 * pi - tmp;
	angle[i] = tmp;	
}
double gettime2(double v, double angle, double r)
{
	return (r * angle)/v;	
}

int main()
{
	scanf("%d%lf",&n,&am);
	for (int i = 0; i < n; ++i)
	{
		a1[i].read();
		b1[i].read();
	}
	int rear = 1;
	a[0] = a1[0];
	b[0] = b1[0];	
	for (int i = 1; i < n; ++i)
	if(b[rear] == a1[i]){
		b[rear] = b1[i];
	}else{
		a[rear] = a1[i];
		b[rear++] = b1[i];
	}
	n = rear;
	
	for (int i = 0; i < n-1; ++i)
	{
		work(i,i+1);
	}	
	vmax[n-1] = 0;
	for (int i = n - 2; i >= 0; --i)
	{
		vmax[i] = min(vc[i], sqrt(2 * am * len(b[i+1] - a[i+1]) + sqr(vmax[i+1])));	
		//cout<<i<<":"<<vmax[i]<<endl;	
	}
	double ans = 0;
	double cur = 0;
	for (int i = 0; i < n; ++i)
	{
		//
		pair<double, double> tmp = gettime(len(b[i] - a[i]), cur, vmax[i]);
		cur = tmp.first;
		//cout<<"cur:"<<cur<<endl;
		ans += tmp.second;
		//cout<<tmp.second<<endl;
		if (i != n-1){
			double ttt = gettime2(cur, angle[i],r[i]);
			//cout<<"time2:"<<ttt<<endl;
			//cout<<"angle:"<<angle[i]<<endl;
			ans += gettime2(cur, angle[i],r[i]);
		}		
		//cout<<"###"<<ans<<endl;
	}
	printf("%.12f\n",ans);
	
	return 0;
}
accuracy: 0.96
time_ms: 20
memory_kb: 5024
final_rank: 16

code_snippet: #include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <iostream>
#include <cstring>

using namespace std;

const double eps = 1e-9;
const double pi = acos(-1.0);
const int maxn = 4e4 + 100;
double am;
int n;
int dcmp(double x){
	return x < -eps? -1 : x > eps;
}

double sqr(double x){
	return x * x;
}

struct point{
	double x, y;
	point(double x = 0, double y = 0):x(x),y(y){}
	void read(){
		scanf("%lf%lf",&x,&y);
	}
	point operator + (const point &b){
		return point(x + b.x, y + b.y);
	}
	point operator - (const point &b){
		return point(x - b.x, y - b.y);
	}
	point operator * (double a){
		return point(x * a, y * a);
	}
	point operator / (double a){
		return point(x / a, y / a);
	}
	bool operator == (const point &b){
		return dcmp(x - b.x)==0 && dcmp(y - b.y)==0;
	}
	
};

point a[maxn],b[maxn];
point a1[maxn],b1[maxn];
double arclen[maxn];
double vmax[maxn],vc[maxn];
double r[maxn];
double angle[maxn];

double dot(point a, point b){
	return a.x*b.x + a.y*b.y;
}
double len2(point a){
	return dot(a,a);
}
double len(point a){
	return sqrt(len2(a));
}
double cross(point a, point b){
	return a.x*b.y - a.y*b.x;
}
point getlineinter(point p, point v, point q, point w){
	point u = p - q;
	double t = cross(w,u) / cross(v,w);
	return p + v*t;
}
point rotate(point a){
	return point (-a.y, a.x);
}
bool rightside(point a1, point b1, point a2){
	point v1 = b1 - a1;
	point v2 = a2 - a1;
	if (cross(v2,v1) > 0)return 1;
	else return 0;
}
pair<double, double> gettime(double len, double v1, double v2)
{
	if (dcmp(2*am*len + sqr(v1) - sqr(v2)) <= 0){
		double v = sqrt(2*am*len + sqr(v1));
		double t = (v - v1)/am;
		return make_pair(v,t);
	}
	if (dcmp(2*am*len + sqr(v2) - sqr(v1)) == 0)return make_pair((v2 - v1)/am, v2);
	double v = sqrt(am*len + (sqr(v1) + sqr(v2))/2);
	double t = (2*v - v1 - v2)/am;
	//cout<<"@@"<<endl;
	return make_pair(v2,t);
}

void work(int i, int j)
{
	point v1 = rotate(b[i] - a[i]);
	point v2 = rotate(b[j] - a[j]);
	point c;
	if (dcmp(cross(v1,v2))==0){
		c = (b[i] + a[j])/2;
	}else{	
	c = getlineinter(b[i], v1, a[j], v2);
	}
	r[i] = len(c - b[i]);
	
	//cout<<r[i]<<endl;
	vc[i] = sqrt(am * r[i]);
	v1 = b[i] - a[i];
	v2 = b[j] - a[j];
	double a2 = atan2(v2.y, v2.x);
	double a1 = atan2(v1.y, v1.x);
	double tmp = a2 - a1;
	if (tmp < 0)tmp += 2 * pi;
	if (rightside(a[i],b[i], a[j]))
		tmp = 2 * pi - tmp;
	angle[i] = tmp;	
}
double gettime2(double v, double angle, double r)
{
	return (r * angle)/v;	
}

int main()
{
	scanf("%d%lf",&n,&am);
	for (int i = 0; i < n; ++i)
	{
		a1[i].read();
		b1[i].read();
	}
	int rear = 1;
	a[0] = a1[0];
	b[0] = b1[0];	
	for (int i = 1; i < n; ++i)
	if(b[rear] == a1[i]){
		b[rear] = b1[i];
	}else{
		a[rear] = a1[i];
		b[rear++] = b1[i];
	}
	n = rear;
	
	for (int i = 0; i < n-1; ++i)
	{
		work(i,i+1);
	}	
	vmax[n-1] = 0;
	for (int i = n - 2; i >= 0; --i)
	{
		vmax[i] = min(vc[i], sqrt(2 * am * len(b[i+1] - a[i+1]) + sqr(vmax[i+1])));	
		//cout<<i<<":"<<vmax[i]<<endl;	
	}
	double ans = 0;
	double cur = 0;
	for (int i = 0; i < n; ++i)
	{
		//
		pair<double, double> tmp = gettime(len(b[i] - a[i]), cur, vmax[i]);
		cur = tmp.first;
		//cout<<"cur:"<<cur<<endl;
		ans += tmp.second;
		//cout<<tmp.second<<endl;
		if (i != n-1){
			double ttt = gettime2(cur, angle[i],r[i]);
			//cout<<"time2:"<<ttt<<endl;
			//cout<<"angle:"<<angle[i]<<endl;
			ans += gettime2(cur, angle[i],r[i]);
		}		
		//cout<<"###"<<ans<<endl;
	}
	printf("%.12f\n",ans);
	
	return 0;
}
accuracy: 0.96
time_ms: 20
memory_kb: 5024
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
typedef double D;
typedef complex<D> P;
typedef pair<P,P> L;
int N;
D acc;
D pi=acos(-1);
L ls[40000];
D rs[40000];
D ths[40000];
D ub[40000];
D cro(P a,P b){return imag(conj(a)*b);}
inline P vec(L l){
	return l.sc-l.fs;
}
inline D verlen(L l,P p){
	return cro(vec(l),p-l.sc)/abs(vec(l));
}
inline P intLL(L a,L b){
	D t=cro(vec(a),a.sc-b.fs)/cro(vec(a),vec(b));
	return b.fs+t*vec(b);
}
inline bool ispal(L a,L b){
	return abs(cro(vec(a),vec(b)))<1e-9;
}
int main(){
	cin>>N>>acc;
	rep(i,N){
		int d,e,f,g;
		cin>>d>>e>>f>>g;
		ls[i]=L(P(d,e),P(f,g));
	}
	rep(i,N-1){
		L a=L(ls[i].sc,ls[i].sc+vec(ls[i])*P(0,1));
		L b=L(ls[i+1].fs,ls[i+1].fs+vec(ls[i+1])*P(0,1));
		P p;
		if(ispal(a,b)) p=(ls[i].sc+ls[i+1].fs)/2.0;
		else p=intLL(a,b);
		rs[i]=verlen(ls[i],p);
		ths[i]=arg(vec(ls[i+1])/vec(ls[i]));
		if(rs[i]<0){
			rs[i]=-rs[i];
			ths[i]=-ths[i];
		}
		if(ths[i]<0) ths[i]+=2*pi;
		assert(0<ths[i]&&ths[i]<2*pi);
	}
	ub[N-1]=0;
	for(int i=N-1;i>0;i--){
		D len=abs(vec(ls[i]));
		ub[i-1]=min(sqrt(ub[i]*ub[i]+2*acc*len),sqrt(rs[i-1]*acc));
	}
	D ans=0,v=0;
	rep(i,N){
		D len=abs(vec(ls[i]));
		D mx=sqrt(v*v+2*acc*len);
		if(mx<=ub[i]){
			ans+=(mx-v)/acc;
			v=mx;
		}else{
			if(ub[i]>v){
				ans+=(ub[i]-v)/acc;
				len=(len-(ub[i]*ub[i]-v*v)/2/acc)/2;
				v=ub[i];
				mx=sqrt(v*v+2*acc*len);
				ans+=2*(mx-v)/acc;
			}else{
				ans+=(v-ub[i])/acc;
				len=(len-(v*v-ub[i]*ub[i])/2/acc)/2;
				mx=sqrt(v*v+2*acc*len);
				ans+=2*(mx-v)/acc;
				v=ub[i];
			}
		}
		if(i==N-1) break;
		ans+=ths[i]*rs[i]/v;
	}
	printf("%.12f\n",ans);
}
accuracy: 1
time_ms: 40
memory_kb: 3456
final_rank: 5

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
typedef double D;
typedef complex<D> P;
typedef pair<P,P> L;
int N;
D acc;
D pi=acos(-1);
L ls[40000];
D rs[40000];
D ths[40000];
D ub[40000];
D cro(P a,P b){return imag(conj(a)*b);}
inline P vec(L l){
	return l.sc-l.fs;
}
inline D verlen(L l,P p){
	return cro(vec(l),p-l.sc)/abs(vec(l));
}
inline P intLL(L a,L b){
	D t=cro(vec(a),a.sc-b.fs)/cro(vec(a),vec(b));
	return b.fs+t*vec(b);
}
inline bool ispal(L a,L b){
	return abs(cro(vec(a),vec(b)))<1e-9;
}
int main(){
	cin>>N>>acc;
	rep(i,N){
		int d,e,f,g;
		cin>>d>>e>>f>>g;
		ls[i]=L(P(d,e),P(f,g));
	}
	rep(i,N-1){
		L a=L(ls[i].sc,ls[i].sc+vec(ls[i])*P(0,1));
		L b=L(ls[i+1].fs,ls[i+1].fs+vec(ls[i+1])*P(0,1));
		P p;
		if(ispal(a,b)) p=(ls[i].sc+ls[i+1].fs)/2.0;
		else p=intLL(a,b);
		rs[i]=verlen(ls[i],p);
		ths[i]=arg(vec(ls[i+1])/vec(ls[i]));
		if(rs[i]<0){
			rs[i]=-rs[i];
			ths[i]=-ths[i];
		}
		if(ths[i]<0) ths[i]+=2*pi;
		assert(0<ths[i]&&ths[i]<2*pi);
	}
	ub[N-1]=0;
	for(int i=N-1;i>0;i--){
		D len=abs(vec(ls[i]));
		ub[i-1]=min(sqrt(ub[i]*ub[i]+2*acc*len),sqrt(rs[i-1]*acc));
	}
	D ans=0,v=0;
	rep(i,N){
		D len=abs(vec(ls[i]));
		D mx=sqrt(v*v+2*acc*len);
		if(mx<=ub[i]){
			ans+=(mx-v)/acc;
			v=mx;
		}else{
			if(ub[i]>v){
				ans+=(ub[i]-v)/acc;
				len=(len-(ub[i]-v)*(ub[i]-v)/2/acc)/2;
				v=ub[i];
				mx=sqrt(v*v+2*acc*len);
				ans+=2*(mx-v)/acc;
			}else{
				ans+=(v-ub[i])/acc;
				len=(len-(ub[i]-v)*(ub[i]-v)/2/acc)/2;
				mx=sqrt(v*v+2*acc*len);
				ans+=2*(mx-v)/acc;
				v=ub[i];
			}
		}
		if(i==N-1) break;
		ans+=ths[i]*rs[i]/v;
	}
	printf("%.12f\n",ans);
}
accuracy: 0.24
time_ms: 40
memory_kb: 3456
final_rank: 20

code_snippet: #include<cstdio>
#include<complex>
#include<cmath>
#include<utility>
#include<algorithm>

using namespace std;

typedef double Real;

const Real eps=1e-9;
const Real PI=acos(-1.0);

typedef pair<Real,Real> P;
typedef complex<Real> Point;
typedef complex<Real> Vector;
typedef pair<Point,Point> Segment;

template<class T> bool eq(T a,T b){
	return abs(a-b)<eps;
}

template<class T> int sgn(T a){
	if(eq(a,0.0)) return 0;
	if(a>0) return 1;
	return -1;
}

Real doP(Vector a,Vector b){
	return (conj(a)*b).real();
}

Real arg(Vector v){
	return atan2(v.imag(),v.real());
}

Real getAng(Segment s1,Segment s2){
	//directed segments, res<=PI
	Vector v1=s1.second-s1.first;
	Vector v2=s2.second-s2.first;
	Vector v=v2/v1;
	Real ang=arg(v);
	ang=abs(ang);
	if(ang>PI) ang=PI*2-ang;
//	printf("ang=%f\n",ang);
	return ang;
}

P getCircle(Segment s1,Segment s2){
	Real theta=getAng(s1,s2);
	Real d=abs(s1.second-s2.first);
	Real radius=1.0/sin(theta/2)*d/2;
//	printf("d=%f,radius=%f\n",d,radius);
	Point p=s1.first,q=s1.second,r=s2.first;
	Real x=doP(p-q,r-q);
	if(sgn(x)>0){
		theta=PI*2-theta;
	}
	return P(radius,theta);
}

Segment segs[40400];

Real ls[40400],Mv[40400];
Real rs[40400],angs[40400];
int N;

Real Ma;

void input(){
	scanf("%d%lf",&N,&Ma);
	for(int i=0;i<N;i++){
		double x1,y1,x2,y2;
		scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
		Point p1=Point(x1,y1);
		Point p2=Point(x2,y2);
		segs[i]=Segment(p1,p2);
	}
}

P solveLine(Real v0,Real x,Real Mlast){
//	printf("solve %f %f %f\n",v0,x,Mlast);
	Real lb=0,ub=x;
	P res;
	bool ok=false;
	for(int stage=0;stage<100;stage++){
		Real mid=(ub+lb)/2;
		Real m=sqrt(v0*v0+2.0*Ma*mid);
		Real t=(m-v0)/Ma;
		Real u2=m*m-2.0*Ma*(x-mid);
		if(u2<-eps){
			lb=mid;
			continue;
		}
		u2=max(u2,0.0);
		Real u=sqrt(u2);
		Real t2=(m-u)/Ma;
		if(sgn(Mlast-u)>=0){
			res=P(u,t+t2);
			lb=mid;
			ok=true;
		}else{
			ub=mid;
		}
	}
	if(ok==false){
		Real t=(v0-Mlast)/Ma;
		return P(Mlast,t);
	}
	return res;
}

Real solve(){
	for(int i=0;i<N-1;i++){
		P p=getCircle(segs[i],segs[i+1]);
		rs[i]=p.first;
		angs[i]=p.second;
		Mv[i]=sqrt(Ma*rs[i]);
//		printf("r=%f,ang=%f,mv=%f\n",rs[i],angs[i],Mv[i]);
	}
	for(int i=0;i<N;i++){
		ls[i]=abs(segs[i].second-segs[i].first);
	}
	Mv[N-1]=0;
	for(int i=N-1;i>=1;i--){
		Real val=2.0*Ma*ls[i];
		Real v0=Mv[i]*Mv[i]+val;
		v0=sqrt(v0);
		Mv[i-1]=min(Mv[i-1],v0);
	}
	Real t=0;
	Real prevv=0;
	for(int i=0;i<N;i++){
		P p=solveLine(prevv,ls[i],Mv[i]);
		t+=p.second;
		prevv=p.first;
		if(isinf(t)){
			printf("%f %f %f\n",prevv,ls[i],Mv[i]);
		}
//		printf("t+=%f\n",p.second);
		if(i!=N-1){
			Real len=angs[i]*rs[i];
//			printf("ang=%f,r=%f,v=%f\n",angs[i],rs[i],prevv);
			Real t2=len/prevv;
			t+=t2;
			if(isinf(t)){
				printf("ang=%f,r=%f,v=%f Mv=%f\n",angs[i],rs[i],prevv,Mv[i]);
				return 0;
			}
		}
	}
	return t;
}

int main(){
	input();
	Real ans=solve();
	printf("%.9f\n",ans);
	return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 3668
final_rank: 13