Problem:
Problem 07:
Crop Circle
アルゼンチンの広大な農地に突如ミステリーサークルが出没した。ミステリーサークルは重なっているもの、ポツンとあるもの、大きいもの、小さいものと合計
n
個確認された。
あるミステリーハンターが空中からミステリーサークルの全体像を撮影しようと試みたところ、各円の輪郭がはっきりしていなかったため、映像にその美しい模様を映し出すことが難しいことが分かった。
そこで、そのミステリーハンターは輪郭に沿って特殊素材の紐を設置し、輪郭を強調する提案をした。
紐を設置する部分は、あるミステリーサークルの円周上で、他のどのミステリーサークルにも含まれない部分である。
撮影隊は必要な紐の長さを計測するために、プログラムの作成をあなたに依頼した。各ミステリーサークルの中心座標と半径を入力し、設置する紐の長さを報告するプログラムを作成せよ。
参考として入出力例の１つ目と２つ目のケースをそれぞれ図１、図２に示す。紐の部分が太い線で示されている。
図１
図２
Input
入力として複数のデータセットが与えられる。各データセットは以下の形式で与えられる：
n
（ミステリーサークルの数：整数）
x
1
y
1
r
1
（1 個目のサークルの中心座標と半径：空白区切りの実数）
x
2
y
2
r
2
（2 個目のサークルの中心座標と半径：空白区切りの実数）
.
.
x
n
y
n
r
n
（
n
個目のサークルの中心座標と半径：空白区切りの実数）
n
が 0 のとき、入力の終わりを示す。
Output
各データセットに対して、紐の長さを１行に出力せよ。出力は 0.000001 以下の誤差を含んでもよい。
Constraints
n
≤ 100
-1000 ≤
x
i
,
y
i
≤ 1000
0 <
r
i
≤ 100
Sample Input
4
6 4 2
4 7 3
7 10 3
13 6 1
4
7 4 2
4 7 3
7 10 3
11 6 3
0
Output for the Sample Input
39.664699289572
45.627024663706

Submitted solutions:

code_snippet: #include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <utility>
#include <queue>
#include <map>
#include <set>
#include <cmath>
#include <deque>
#include <algorithm>
#include <stack>
#include <sstream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <complex>
#include <cassert>

/*-----------------------*/
//#define int long long
#define INF 0x3f3f3f3f
#define INF2 0x7f7f7f7f
using namespace std;
/*-----------------------*/

const double pi = acos(-1.);

//double squ(double x){
//    return x*x;
//}
//
//struct Point{
//    double x, y;
//    Point(double x=0, double y=0) :x(x), y(y){ }
//};
//
//typedef Point Vector;
//
//Vector operator + (Vector A, Vector B){ return Vector(A.x+B.x, A.y+B.y);}
//
//Vector operator - (Point A, Point B) { return Vector(A.x-B.x, A.y-B.y);}
//
//Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p);}
//
//Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p);}
//
//bool operator < (const Point& a, const Point& b){
//    return a.x < b.x || (a.x == b.x && a.y < b.y);
//}
//
const double eps = 1e-10;
int dcmp(double x){
    if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;
}
//
//bool operator == (const Point& a, const Point& b){
//    return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;
//}
//



//
//double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x;}
//double Area2(Point A, Point B, Point C) { return Cross(B-A, C-A);}
//
//Vector Rotate(Vector A, double rad){
//    return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
//}
//
////计算向量的单位法线。即左转90度，再把长度归一化。
//Vector Normal(Vector A){
//    double L = Length(A);
//    return Vector(-A.y/L, A.x/L);
//}





using int64 = long long;
//const int mod = 1e9 + 7;
const int mod = 998244353;

const int64 infll = (1LL << 62) - 1;
const int inf = (1 << 30) - 1;

struct IoSetup {
    IoSetup() {
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(10);
        cerr << fixed << setprecision(10);
    }
} iosetup;


template< typename T1, typename T2 >
ostream &operator<<(ostream &os, const pair< T1, T2 > &p) {
    os << p.first << " " << p.second;
    return os;
}

template< typename T1, typename T2 >
istream &operator>>(istream &is, pair< T1, T2 > &p) {
    is >> p.first >> p.second;
    return is;
}

template< typename T >
ostream &operator<<(ostream &os, const vector< T > &v) {
    for(int i = 0; i < (int) v.size(); i++) {
        os << v[i] << (i + 1 != v.size() ? " " : "");
    }
    return os;
}

template< typename T >
istream &operator>>(istream &is, vector< T > &v) {
    for(T &in : v) is >> in;
    return is;
}

template< typename T1, typename T2 >
inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }

template< typename T1, typename T2 >
inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }

template< typename T = int64 >
vector< T > make_v(size_t a) {
    return vector< T >(a);
}

template< typename T, typename... Ts >
auto make_v(size_t a, Ts... ts) {
    return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...));
}

template< typename T, typename V >
typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) {
    t = v;
}

template< typename T, typename V >
typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) {
    for(auto &e : t) fill_v(e, v);
}

template< typename F >
struct FixPoint : F {
    FixPoint(F &&f) : F(forward< F >(f)) {}

    template< typename... Args >
    decltype(auto) operator()(Args &&... args) const {
        return F::operator()(*this, forward< Args >(args)...);
    }
};

template< typename F >
inline decltype(auto) MFP(F &&f) {
    return FixPoint< F >{forward< F >(f)};
}

namespace geometry {
    using Real = double;
    const Real EPS = 1e-8;
    const Real PI = acos(static_cast< Real >(-1));

    inline int sign(const Real &r) {
        return r <= -EPS ? -1 : r >= EPS ? 1 : 0;
    }

    inline bool equals(const Real &a, const Real &b) {
        return sign(a - b) == 0;
    }
}

namespace geometry {
    using Point = complex< Real >;

    istream &operator>>(istream &is, Point &p) {
        Real a, b;
        is >> a >> b;
        p = Point(a, b);
        return is;
    }

    ostream &operator<<(ostream &os, const Point &p) {
        return os << real(p) << " " << imag(p);
    }

    Point operator*(const Point &p, const Real &d) {
        return Point(real(p) * d, imag(p) * d);
    }

    // rotate point p counterclockwise by theta rad
    Point rotate(Real theta, const Point &p) {
        return Point(cos(theta) * real(p) - sin(theta) * imag(p), sin(theta) * real(p) + cos(theta) * imag(p));
    }

    Real cross(const Point &a, const Point &b) {
        return real(a) * imag(b) - imag(a) * real(b);
    }

    Real dot(const Point &a, const Point &b) {
        return real(a) * real(b) + imag(a) * imag(b);
    }

    bool compare_x(const Point &a, const Point &b) {
        return equals(real(a), real(b)) ? imag(a) < imag(b) : real(a) < real(b);
    }

    bool compare_y(const Point &a, const Point &b) {
        return equals(imag(a), imag(b)) ? real(a) < real(b) : imag(a) < imag(b);
    }

    using Points = vector< Point >;
}

namespace geometry {
    struct Line {
        Point a, b;

        Line() = default;

        Line(const Point &a, const Point &b) : a(a), b(b) {}

        Line(const Real &A, const Real &B, const Real &C) { // Ax+By=C
            if(equals(A, 0)) {
                assert(!equals(B, 0));
                a = Point(0, C / B);
                b = Point(1, C / B);
            } else if(equals(B, 0)) {
                a = Point(C / A, 0);
                b = Point(C / A, 1);
            } else {
                a = Point(0, C / B);
                b = Point(C / A, 0);
            }
        }

        friend ostream &operator<<(ostream &os, Line &l) {
            return os << l.a << " to " << l.b;
        }

        friend istream &operator>>(istream &is, Line &l) {
            return is >> l.a >> l.b;
        }
    };

    using Lines = vector< Line >;
}

namespace geometry {
    struct Segment : Line {
        Segment() = default;

        using Line::Line;
    };

    using Segments = vector< Segment >;
}

namespace geometry {
    // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
    constexpr int COUNTER_CLOCKWISE = +1;
    constexpr int CLOCKWISE = -1;
    constexpr int ONLINE_BACK = +2; // c-a-b
    constexpr int ONLINE_FRONT = -2; // a-b-c
    constexpr int ON_SEGMENT = 0; // a-c-b
    int ccw(const Point &a, Point b, Point c) {
        b = b - a, c = c - a;
        if(sign(cross(b, c)) == +1) return COUNTER_CLOCKWISE;
        if(sign(cross(b, c)) == -1) return CLOCKWISE;
        if(sign(dot(b, c)) == -1) return ONLINE_BACK;
        if(norm(b) < norm(c)) return ONLINE_FRONT;
        return ON_SEGMENT;
    }
}

namespace geometry {
    // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
    Point projection(const Line &l, const Point &p) {
        auto t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
        return l.a + (l.a - l.b) * t;
    }
}

namespace geometry {
    Real distance_lp(const Line &l, const Point &p) {
        return abs(p - projection(l, p));
    }
}

namespace geometry {
    // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
    bool is_parallel(const Line &a, const Line &b) {
        return equals(cross(a.b - a.a, b.b - b.a), 0.0);
    }
}

namespace geometry {
    bool is_intersect_ll(const Line &l, const Line &m) {
        Real A = cross(l.b - l.a, m.b - m.a);
        Real B = cross(l.b - l.a, l.b - m.a);
        if(equals(abs(A), 0) && equals(abs(B), 0)) return true;
        return !is_parallel(l, m);
    }
}

namespace geometry {
    bool is_intersect_sp(const Segment &s, const Point &p) {
        return ccw(s.a, s.b, p) == ON_SEGMENT;
    }
}


namespace geometry {
    Real distance_ll(const Line &l, const Line &m) {
        return is_intersect_ll(l, m) ? 0 : distance_lp(l, m.a);
    }
}

namespace geometry {
    Real distance_sp(const Segment &s, const Point &p) {
        Point r = projection(s, p);
        if(is_intersect_sp(s, r)) return abs(r - p);
        return min(abs(s.a - p), abs(s.b - p));
    }
}

namespace geometry {
    bool is_intersect_ss(const Segment &s, const Segment &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;
    }
}


namespace geometry {
    Real distance_ss(const Segment &a, const Segment &b) {
        if(is_intersect_ss(a, b)) return 0;
        return min({distance_sp(a, b.a), distance_sp(a, b.b), distance_sp(b, a.a), distance_sp(b, a.b)});
    }
}

using namespace geometry;

struct Leg{
    double ang;
    int id;

    bool operator < (const Leg& o) const{
        return ang < o.ang;
    }
};

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

struct Circle{
    double x, y, r;
    double valid_ang;
    vector<Leg> v;
};
vector<Circle> circles;
int top = 0;
bool vis[1000050];
int tot_vis;
pair<Point, Point> inter(Circle a, Circle b){

    double R = sqrt(squ(a.x-b.x) + squ(a.y-b.y));
    Point ans1 = Point(a.x+b.x, a.y+b.y)*0.5 + Point(b.x-a.x, b.y-a.y)*(squ(a.r) - squ(b.r))/(2*squ(R))
                 + Point(b.y-a.y, a.x - b.x) *0.5 * sqrt(2*((squ(a.r)+squ(b.r))/squ(R)) - squ(squ(a.r) - squ(b.r))/squ(squ(R)) - 1);
    Point ans2 = Point(a.x+b.x, a.y+b.y)*0.5 + Point(b.x-a.x, b.y-a.y)*(squ(a.r) - squ(b.r))/(2*squ(R))
                 - Point(b.y-a.y, a.x - b.x) *0.5 * sqrt(2*((squ(a.r)+squ(b.r))/squ(R)) - squ(squ(a.r) - squ(b.r))/squ(squ(R)) - 1);
    return make_pair(ans1, ans2);
}
double Dot(Point A, Point B) {return A.real()*B.real() + A.imag()*B.imag();}
double Length(Point A) { return sqrt(Dot(A, A));}
double Angle(Point A, Point B) { return acos(Dot(A, B) / Length(A) / Length(B));}

double dir(Point A){
    if(A.imag() >= 0) return Angle(Point(1, 0), A);
    return 2*pi- Angle(Point(1, 0), A);
}



signed main() {

#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif


    int n;
    while(~scanf("%d", &n) && n){
        circles.clear();
        top = 0;

        for(int i = 0; i<n; i++){
            double x, y, r; scanf("%lf%lf%lf", &x, &y, &r);
            circles.push_back({x, y, r, 2 * pi});
        }

        for(int i = 0; i<n; i++){
            for(int j = 0; j<n; j++){
                if(i == j)continue;
                Circle& c1 = circles[i];
                Circle& c2 = circles[j];
                if(dcmp(squ(c1.x-c2.x)+squ(c1.y-c2.y) -squ(c1.r+c2.r)) >= 0) continue;
                if(dcmp(squ(c1.x-c2.x)+squ(c1.y-c2.y) -squ(c1.r-c2.r)) <= 0){
                    if(dcmp(c1.r - c2.r) > 0){
                        c2.valid_ang = 0;
                    }else{
                        c1.valid_ang = 0;
                    }
                    continue;
                }

                Point o1(c1.x, c1.y);
                Point o2(c2.x, c2.y);

                pair<Point, Point> ppp = inter(c1, c2);

                Point p1 = ppp.first;
                Point p2 = ppp.second;


                Point A = o1 + Point(o2.real()-o1.real(), o2.imag()-o1.imag()) / sqrt(squ(o2.real()-o1.real()) + squ(o2.imag()-o1.imag())) * c1.r;
                Point B = o1 - Point(o2.real()-o1.real(), o2.imag()-o1.imag()) / sqrt(squ(o2.real()-o1.real()) + squ(o2.imag()-o1.imag())) * c1.r;
                double len1 = squ(A.real()-o2.real()) + squ(A.imag()-o2.imag());
                double len2 = squ(B.real()-o2.real()) + squ(B.imag()-o2.imag());
                if(dcmp(len1 - len2) < 0){
                    swap(len1,len2);
                    swap(A, B);
                }
                Point v1 = B-o1;
                Point v2 = p1-o1;
                bool flag = dcmp(Angle(v1, v2) - pi/2.) <= 0;


                double big_dir = dir(p1 - o1);
                double small_dir = dir(p2 - o1);
                if(dcmp(big_dir-small_dir) < 0) swap(big_dir, small_dir);
                double small_diff = abs(big_dir - small_dir);
                double big_diff = 2*pi-small_diff;
                if(dcmp(small_diff - big_diff) > 0) swap(small_diff, big_diff);

                bool flag_zero = dcmp(2*pi-big_dir+small_dir - pi) < 0;

                if(flag && flag_zero || !flag && !flag_zero){
                    c1.v.push_back(Leg{big_dir, top});
                    c1.v.push_back(Leg{2*pi-1e-10, top});
                    top++;
                    c1.v.push_back(Leg{0+1e-10, top});
                    c1.v.push_back(Leg{small_dir, top});
                    top++;
                }else{
                    c1.v.push_back(Leg{small_dir, top});
                    c1.v.push_back(Leg{big_dir, top});
                    top++;
                }


            }
        }

        for(int i = 0; i<n; i++){
            memset(vis, 0, sizeof(vis));
            tot_vis = 0;

            sort(circles[i].v.begin(), circles[i].v.end());

            double last_ang = -1.;
            for(Leg const& leg : circles[i].v){
                if(vis[leg.id]){
                    vis[leg.id] = false;
                    tot_vis--;
                    if(tot_vis == 0){
                        circles[i].valid_ang -= leg.ang-last_ang;
                    }
                }else{
                    if(tot_vis == 0){
                        last_ang = leg.ang;
                    }
                    vis[leg.id] = true;
                    tot_vis++;
                }
            }

        }

        double ans = 0;
        for(int i = 0; i<n; i++){
            Circle &c = circles[i];
            if(dcmp(c.valid_ang) <= 0) continue;
//            cout << "eq" << i+1 << ": " << "rad= " << c.valid_ang << "  " << "c= " << c.r*c.valid_ang <<  endl;
            ans += c.r*c.valid_ang;
        }
        printf("%.12lf\n", ans);



    }


    return 0;

}
accuracy: 1
time_ms: 10
memory_kb: 4800
final_rank: 12

code_snippet: #include <bits/stdc++.h>

using namespace std;
using ll = long long;
// #define int ll
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()

template<typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template<typename T> bool IN(T a, T b, T x) { return a<=x&&x<b; }
template<typename T> T ceil(T a, T b) { return a/b + !!(a%b); }

template<typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}
template<typename T,typename V> typename enable_if<is_class<T>::value==0>::type
fill_v(T &t, const V &v) { t=v; }
template<typename T,typename V> typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t, const V &v ) { for(auto &e:t) fill_v(e,v); }

template<class S,class T>
ostream &operator <<(ostream& out,const pair<S,T>& a) {
    out<<'('<<a.first<<','<<a.second<<')'; return out;
}
template<class T>
ostream &operator <<(ostream& out,const vector<T>& a){
    out<<'[';
    for(const T &i: a) out<<i<<',';
    out<<']';
    return out;
}
template<class T>
ostream &operator <<(ostream& out, const set<T>& a) {
    out<<'{';
    for(const T &i: a) out<<i<<',';
    out<<'}';
    return out;
}
template<class T, class S>
ostream &operator <<(ostream& out, const map<T,S>& a) {
    out<<'{';
    for(auto &i: a) out<<i<<',';
    out<<'}';
    return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; // DRUL
const int INF = 1<<30;
const ll LLINF = 1LL<<60;
const ll MOD = 1000000007;

using R = long double; // Rにmint渡せるようにする
using P = complex<R>;
using L = pair<P,P>;
using G = vector<P>;
struct C {
    P c; R r;
    C() {}
    C(const P &a, const R &b) : c(a), r(b) {}
};
struct S : public L {
    S() {}
    S(const P &a, const P &b) : L(a,b) {}
};

const R EPS = 1e-8;
const R PI = atan(1)*4;

inline int sgn(const R& r) { return (r>EPS) - (r<-EPS); }
inline R dot(const P& a, const P& b) {
    return real(a)*real(b) + imag(a)*imag(b);
}
inline R det(const P& a, const P& b) {
    return real(a)*imag(b) - imag(a)*real(b);
}
inline P vec(const L& l) {return l.second - l.first;}
namespace std {
	bool operator < (const P& a, const P& b) {
		return sgn(real(a-b)) ? real(a-b) < 0 : sgn(imag(a-b)) < 0;
	}
	bool operator == (const P& a, const P& b) {
		return sgn(real(a-b)) == 0 && sgn(imag(a-b)) == 0;
	}
    bool cmp_y (const P& a, const P& b) {
        return sgn(imag(a-b)) ? imag(a-b) < 0 : sgn(real(a-b)) < 0;
    }
}

// P,L,Sについて入力
inline istream& operator>>(istream& is, P& p) {
    R x, y;
    is >> x >> y;
    p = P(x, y);
    return is;
}
inline istream& operator>>(istream& is, L& l) {
    P a, b;
    is >> a >> b;
    l = L(a, b);
    return is;
}
inline istream& operator>>(istream& is, S& s) {
    P a, b;
    is >> a >> b;
    s = S(a, b);
    return is;
}

// 線分abから見たcの位置
enum CCW{LEFT=1, RIGHT=2, BACK=4, FRONT=8, ON_SEG=16};
int ccw(P a, P b, P c) {
	P p = (c-a)/(b-a);
	if(sgn(imag(p)) > 0) return LEFT;
	if(sgn(imag(p)) < 0) return RIGHT;
	if(sgn(real(p)) < 0) return BACK;
	if(sgn(real(p)-1) > 0) return FRONT;
	return ON_SEG;
}

int intersect(const C& a, const C& b) {
	R dist = sqrt(norm(a.c-b.c)), r1 = a.r + b.r, r2 = abs(a.r - b.r);
	if(sgn(r1-dist) < 0)  return 4;	// 円が離れている
	if(sgn(r1-dist) == 0) return 3;	// 外接
	if(sgn(r2-dist) < 0 && sgn(dist-r1) < 0) return 2; // 交差
	if(sgn(dist-r2) == 0) return 1; // 内接
	return 0;	// 内部に含む
}

vector<P> crosspoint(C a, C b) {
	R d = abs(a.c-b.c);
	R t = (a.r*a.r-b.r*b.r+d*d)/2/d, h = sqrt(a.r*a.r-t*t);
	P m = t/abs(b.c-a.c)*(b.c-a.c)+a.c;
    auto n_vector = [&](P p) -> P { return P(-p.imag(), p.real())/abs(p); };
	P n = n_vector(a.c-b.c);
	vector<P> ret(2, m);
	ret[0] -= h*n; ret[1] += h*n;
	if(ret[1] < ret[0]) swap(ret[0], ret[1]);
	return ret;
}

signed main(void)
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    while(1) {
        ll n;
        cin >> n;
        if(!n) break;
        vector<C> cir(n);
        REP(i, n) cin >> cir[i].c >> cir[i].r;

        R ans = 0;
        REP(i, n) {
            bool flag = true;
            vector<pair<R,P>> v;
            REP(j, n) {
                if(i == j) continue;
                if(intersect(cir[i], cir[j]) <= 1 && cir[i].r < cir[j].r) {
                    flag = false;
                    break;
                } else if(intersect(cir[i], cir[j]) == 2) {
                    auto vp = crosspoint(cir[i], cir[j]);
                    for(auto p: vp) {
                        R ang = atan2(cir[i].c.imag()-p.imag(), cir[i].c.real()-p.real());
                        v.push_back({ang, p});
                    }
                }
            }
            if(!flag) continue;
            sort(ALL(v));
            // cout << "i=" << i << " " << v << endl;
            if(v.size() == 0) ans += 2*PI*cir[i].r;
            REP(j, v.size()) {
                // 弧v[j],v[j+1]が他の円に含まれているか
                R diff;
                if(j+1 == (ll)v.size()) diff = v[0].first-v[j].first+2*PI;
                else diff = v[j+1].first-v[j].first;
                R arg = v[j].first + diff/2;
                P m = {cir[i].c.real() + cos(arg+PI) * cir[i].r,
                    cir[i].c.imag() + sin(arg+PI) * cir[i].r};
                // cout << arg << " " << cos(arg+PI) << " " << sin(arg+PI) << endl;
                bool flag = true;
                REP(k, n) {
                    if(i == k) continue;
                    if(sgn(abs(cir[k].c - m) - cir[k].r) < 0) {
                        flag = false;
                        break;
                    }
                }
                // cout << a << " " << b << " " << diff << " " << arg << " " << m << " " << flag << endl;
                if(flag) ans += cir[i].r * diff;
            }
        }

        cout << fixed << setprecision(9) << ans << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3596
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define rep(i,n) for(int i=0,i##_cond=(n);i<i##_cond;++i)
#define all(a) (a).begin(),(a).end()

const double EPS = 1e-8;
// 点
typedef complex<double> P;
namespace std {
  bool isnan(const P&p){
    return isnan(p.real()) or isnan(p.imag());
  }
}

// 円
struct C {
  P p; double r;
  C(const P &p_, double r_) : p(p_), r(r_) { }
};

// 点同士
double distancePP(const P &p, const P &q){
  return abs(p-q);
}
// 円同士の交点
// 1点または2点で交わることを要求する
// 交わらない時はnanを返す
pair<P, P> crosspointCC(const C& c1, const C& c2) {
    double d = abs(c1.p - c2.p);
    double rc = (d*d + c1.r*c1.r - c2.r*c2.r) / (2*d);
    double rs = sqrt(c1.r*c1.r - rc*rc);
    P diff = (c2.p - c1.p) / d;
    return make_pair(c1.p + diff * P(rc, rs), c1.p + diff * P(rc, -rs));
}

// 入力
int n;
vector<C> cs;

// 点が全ての円に含まれないか
bool notInclude(const P &p){
  bool f = true;
  rep(j,n)
    if(distancePP(cs[j].p,p) + EPS < cs[j].r) // 内部にある
      f = false;
  return f;
}

// i番目の円について
double calc(int i){
  double res = 0;

  // 交点を列挙
  vector<P> ps; // 交点
  rep(j,n){
    if(i == j) continue;

    auto pp = crosspointCC(cs[i],cs[j]);
    if(not isnan(pp.first))
      ps.push_back(pp.first);
    if((not isnan(pp.second)) and pp.first != pp.second)
      ps.push_back(pp.second);
  }

  // 半時計回りにソート
  auto g = [&](const P &p, const P &q){
    P tmpp = p - cs[i].p, tmpq = q - cs[i].p;
    return arg(tmpp) < arg(tmpq);
  };
  sort(all(ps),g);

  // 各区間がカウントされるかチェック
  if(ps.size() == 0){
    // 交点がなければどこでもいい
    P tmp{cs[i].p.real(), cs[i].p.imag()+cs[i].r};
    if(notInclude(tmp))
      res += 2 * M_PI * cs[i].r;
    
  }else if(ps.size() == 1){
    // どこかで接していたら反対側をとる
    P op = ps[0] - P(2,0)*(ps[0]-cs[i].p);
    if(notInclude(op))
      res += 2 * M_PI * cs[i].r;
    
  }else{
    rep(k,ps.size()){
      P a = ps[k]-cs[i].p, b = ps[(k+1)%ps.size()]-cs[i].p;

      double midd = (arg(a)+arg(b))/2;
      P midp = cs[i].p + P(cs[i].r*cos(midd),cs[i].r*sin(midd));
      if(arg(a) > arg(b)) 
	midp = midp - P(2,0)*(midp-cs[i].p);

      if(notInclude(midp)){
	if(arg(a) < arg(b)){
	  double tmp = (arg(b)-arg(a)) * cs[i].r;
	  res += tmp;
	}else{
	  double tmp = (2*M_PI + arg(b)-arg(a)) * cs[i].r;
	  res += tmp;
	}
      }
    }
  }
  
  return res;
}

signed main(){
  while(cin >> n, n){
    cs.clear();
    rep(i,n){
      double x,y,r; cin >> x >> y >> r;
      P tmp(x,y);
      cs.emplace_back(tmp,r);
    }
    double ans = 0;
    rep(i,n){
      double tmp = calc(i);
      ans += tmp;
    }
    printf("%.10lf\n",ans);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3524
final_rank: 10

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


/* ??????????????¬ */

#include <complex>

typedef complex<ld> Point;
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(x) (x).begin(),(x).end()


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 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)));
}


//???????????´?????????????????????
//???????????´??????????????§???????????¨????¢?????????¨?????????
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(bisection(Line(vertics[0], vertics[1]), Line(vertics[0], vertics[2])));
	Line bi2(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(bisection(Line(vertics[i], vertics[i] * 2.0l - vertics[(i + 2) % 3]), Line(vertics[i], vertics[(i + 1) % 3])));
		Line bi2(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(bisection(ls[0], ls[1]));
	vector<Point>ecs;

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


	Line bbi(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 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(), all(nret));
	}
	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;
	}

}

/* ????§???¢ */

typedef vector<Point> Polygon;

// ??¢???
ld area(const Polygon &p) {
	ld res = 0;
	int n = p.size();
	rep(j, n) res += cross(p[j], p[(j + 1) % n]);
	return res / 2;
}

//????§???¢????????¢??????
bool is_counter_clockwise(const Polygon &poly) {
	ld angle = 0;
	int n = poly.size();
	rep(i, n) {
		Point a = poly[i], b = poly[(i + 1) % n], c = poly[(i + 2) % n];
		angle += arg((c - b) / (b - a));
	}
	return angle > eps;
}

// ??????????????????
/*0 => out
1 => on
2 => in*/
int is_in_Polygon(const Polygon &poly, const  Point& p) {
	ld angle = 0;
	int n = poly.size();
	rep(i, n) {
		Point a = poly[i], b = poly[(i + 1) % n];
		if (isis_sp(Line(a, b), p)) return 1;
		angle += arg((b - p) / (a - p));
	}
	return eq(angle, 0) ? 0 : 2;
}
//??????????????????2?????????
enum { out, on, in };
int convex_contains(const Polygon &P, const Point &p) {
	const int n = P.size();
	Point g = (P[0] + P[n / 3] + P[2 * n / 3]) / 3.0l; // inner-point
	int a = 0, b = n;
	while (a + 1 < b) { // invariant: c is in fan g-P[a]-P[b]
		int c = (a + b) / 2;
		if (cross(P[a] - g, P[c] - g) > 0) { // angle < 180 deg
			if (cross(P[a] - g, p - g) > 0 && cross(P[c] - g, p - g) < 0) b = c;
			else                                                  a = c;
		}
		else {
			if (cross(P[a] - g, p - g) < 0 && cross(P[c] - g, p - g) > 0) a = c;
			else                                                  b = c;
		}
	}
	b %= n;
	if (cross(P[a] - p, P[b] - p) < 0) return 0;
	if (cross(P[a] - p, P[b] - p) > 0) return 2;
	return 1;
}

// ??????
//???????????????????????¨????????????????????§??¨???
Polygon convex_hull(vector<Point> ps) {
	int n = ps.size();
	int k = 0;
	sort(ps.begin(), ps.end());
	Polygon ch(2 * n);
	for (int i = 0; i < n; ch[k++] = ps[i++])
		while (k >= 2 && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
	for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = ps[i--])
		while (k >= t && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0) --k;
	ch.resize(k - 1);
	return ch;
}



//????????????
vector<Polygon> convex_cut(const Polygon &ps, const Line& l) {
	int n = ps.size();
	Polygon q;
	Polygon r;
	rep(i, n) {
		Point a = ps[i], b = ps[(i + 1) % n];
		Line m = Line(a, b);
		if (ccw(l.a, l.b, a) != -1) q.push_back(a);
		if (ccw(l.a, l.b, a) != 1) r.push_back(a);
		if (ccw(l.a, l.b, a) * ccw(l.a, l.b, b) < 0 && isis_ll(l, m)) {
			q.push_back(is_ll(l, m));
			r.push_back(is_ll(l, m));
		}
	}
	const vector<Polygon>polys{ q,r };
	return polys;
}


/* ??¢??¬??????????????? */
void add_Point(vector<Point> &ps, const Point p) {
	for (Point q : ps) if (abs(q - p) < eps) return;
	ps.push_back(p);
}

typedef int Weight;
struct edge {
	int src, dst;
	Weight weight;
	edge(int src, int dst, Weight weight) :
		src(src), dst(dst), weight(weight) { }
};

typedef vector<edge> edges;
typedef vector<edges> graph;

void add_edge(graph &g, const int from, const int to, const Weight& weight) {
	g[from].push_back(edge{ from, to, weight });
}

graph segment_arrangement(const vector<Line> &s, const vector<Point> &p) {
	int n = p.size(), m = s.size();
	graph g(n);
	rep(i, m) {
		vector<pair<ld, int>> vec;
		rep(j, n) if (isis_sp(s[i], p[j]))
			vec.emplace_back(abs(s[i].a - p[j]), j);
		sort(all(vec));
		rep(j, vec.size() - 1) {
			int from = vec[j].second, to = vec[j + 1].second;
			add_edge(g, from, to, static_cast<Weight>(abs(p[from] - p[to])));
		}
	}
	return g;
}
graph sennbunn_arrangement(const vector<Line>&s) {
	vector<Point>crss;
	for (int i = 0; i < static_cast<int>(s.size()); ++i) {
		for (int j = i + 1; j < static_cast<int>(s.size()); ++j) {
			if (isis_ss(s[i], s[j])) {
				crss.push_back(is_ll2(s[i], s[j])[0]);
			}
		}
	}
	for (int i = 0; i <static_cast<int>(s.size()); ++i) {
		crss.push_back(s[i][0]);
		crss.push_back(s[i][1]);
	}
sort(crss.begin(), crss.end());
crss.erase(unique(crss.begin(), crss.end()), crss.end());
	return segment_arrangement(s, crss);
}

graph Circle_arrangement(const vector<Circle> &c, const vector<Point> &p) {
	int n = p.size(), m = c.size();
	graph g(n);
	rep(i, m) {
		vector<pair<ld, int>> vec;
		rep(j, n) if (abs(abs(c[i].p - p[j]) - c[i].r) < eps)
			vec.emplace_back(arg(c[i].p - p[j]), j);
		sort(all(vec));
		rep(j, vec.size() - 1) {
			int from = vec[j].second, to = vec[j + 1].second;
			ld angle = vec[j + 1].first - vec[j].first;
			add_edge(g, from, to, static_cast<Weight>(angle * c[i].r));
		}
		if (vec.size() >= 2) {
			int from = vec.back().second, to = vec.front().first;
			ld angle = vec.front().first - vec.back().first;
			add_edge(g, from, to, static_cast<Weight>(angle * c[i].r));
		}
	}
	return g;
}

int main() {
	cout << setprecision(11) << fixed;
	while (1) {
		int N; cin >> N;
		if (!N)break;
		vector<Circle>cs;
		for (int i = 0; i < N; ++i) {
			ld x, y, r; cin >> x >> y >> r;
			cs.push_back(Circle(Point(x, y), r));
		}
		vector<vector<ld>>contacts(N);
		for (int i = 0; i < N; ++i) {
			for (int j = 0; j < N; ++j) {
				if (i == j)continue;
				else {
					vector<Point>cons = is_cc(cs[i], cs[j]);
					for (auto con : cons) {
						Point avec = con - cs[i].p;
						contacts[i].push_back(arg(avec));
					}
				}
			}
		}
		for (auto &contact : contacts) {
			sort(contact.begin(), contact.end());
		}


		ld ans = 0;
		for (int i = 0; i < N; ++i) {
			vector<ld>contact = contacts[i];
			if(contact.empty()||contact.size()==1){
				bool flag = true;
				for (int j = 0; j < N; ++j) {
					if (i == j)continue;
					else {
						if (Circle_in_Circle(cs[i], cs[j]))flag = false;
					}
				}
				if (flag)ans += cs[i].r*2*pi;
			}
			else {
				for (int j = 0; j < contact.size(); ++j) {
					ld amid = j == contact.size() - 1 ? (2*pi+contact[0] + contact[contact.size() - 1])/2 : (contact[j + 1] + contact[j])/2;
					ld sa= j == contact.size() - 1 ? 2*pi+contact[0] - contact[contact.size() - 1] : contact[j + 1] - contact[j];
					Point avec(cs[i].p.real() + cs[i].r*cos(amid), cs[i].p.imag() + cs[i].r*sin(amid));
					
					bool flag = true;
					for (int j = 0; j < N; ++j) {
						if (i == j)continue;
						else {
							if (Circle_in_Circle(cs[i], cs[j]))flag = false;
							if (is_in_Circle(cs[j], avec))flag = false;
						}
					}
					if (flag)ans += cs[i].r*sa;
				}
			}
		}
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 3584
final_rank: 15

code_snippet: /*include*/
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#include<utility>
#include<vector>
#include<cmath>
#include<cstdio>
#include<complex>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define rp(a) while(a--)
#define pb push_back
#define mp make_pair
#define it ::iterator
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
const double PI=acos(-1);
const double EPS=1e-10;
const double inf=1e8;
using namespace std;
#define shosu(x) fixed<<setprecision(x)
typedef complex<double> P;
typedef vector<P> G;
typedef vector<int> vi;
typedef vector<vi> vvi;

struct L : public vector<P> {
  L(const P &a, const P &b) {
    push_back(a); push_back(b);
  }
};
struct C{
	P c;double r;
	C(const P &c,double r):c(c),r(r){}
};
#define curr(P, i) P[i]
#define next(P, i) P[(i+1)%P.size()]
#define diff(P, i) (next(P, i) - curr(P, i))
namespace std {
	bool operator < (const P& a, const P& b) {
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
		//return imag(a) != imag(b) ? imag(a) < imag(b) : real(a) < real(b);  
	}
	bool operator == (const P& a, const P& b) {
		return a.real()==b.real()&&a.imag()==b.imag();
	}
}
P pin(){
	double x,y;
	char d;
	cin>>x>>y;
	P p(x,y);
	return p;
}
void PIN(P* a,int n){
	rep(i,n)a[i]=pin();
}
double dot(P a,P b){
	return real(conj(a)*b);
}
double cross(P a,P b){
	return imag(conj(a)*b);
}
int ccw(P a, P b, P c) {
  b -= a; c -= a;
  if (cross(b, c) > 0)   return +1;       // counter clockwise
  if (cross(b, c) < 0)   return -1;       // clockwise
  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;
}
P projection(L a,P p){
	double t=dot(p-a[0],a[0]-a[1])/norm(a[0]-a[1]);
	return a[0]+t*(a[0]-a[1]);
}
P reflection(L a,P p){
	return p+2.0*(projection(a,p)-p);
}
bool intersectLL(const L &l, const L &m) {
  return abs(cross(l[1]-l[0], m[1]-m[0])) > EPS || // non-parallel
         abs(cross(l[1]-l[0], m[0]-l[0])) < EPS;   // same line
}
bool intersectLS(const L &l, const L &s) {
  return cross(l[1]-l[0], s[0]-l[0])*       // s[0] is left of l
         cross(l[1]-l[0], s[1]-l[0]) < EPS; // s[1] is right of l
}
bool intersectLP(const L &l, const P &p) {
  return abs(cross(l[1]-p, l[0]-p)) < EPS;
}
bool intersectSS(const L &s, const L &t) {
  return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 &&
         ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;
}
bool intersectSP(const L &s, const P &p) {
  return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS; // triangle inequality
}
double distanceLP(const L &l, const P &p) {
	return abs(p - projection(l, p));
}
double distanceLL(const L &l, const L &m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
double distanceLS(const L &l, const L &s) {
  if (intersectLS(l, s)) return 0;
  return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
double distanceSP(const L &s, const P &p) {
  const P r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s[0] - p), abs(s[1] - p));
}
double distanceSS(const L &s, const L &t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
             min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}
/*bool intersectCS(C c,const L &l){
    return (distanceLP(l,c.c) < c.r+EPS &&
            (c.r < abs(c.c-l[0]) + EPS || c.r < abs(c.c-l[1]) + EPS));
}*/
int intersectCS(C c,L &l){
	if(norm(projection(l,c.c)-c.c)-c.r*c.r>EPS)return 0;
	const double d1=abs(c.c-l[0]),d2=abs(c.c-l[1]);
	if(d1<c.r+EPS&&d2<c.r+EPS)return 0;
	if(d1<c.r-EPS&&d2>c.r+EPS||d1>c.r+EPS&&d2<c.r-EPS)return 1;
	const P h=projection(l,c.c);
	if(dot(l[0]-h,l[1]-h)<0)return 2;
	return 0;
}
P crosspointSS(L a,L b){
	double t1=abs(cross(a[1]-a[0],b[0]-a[0]));
	double t2=abs(cross(a[1]-a[0],b[1]-a[0]));
	return b[0]+(b[1]-b[0])*t1/(t1+t2);
}
L crosspointCL(C c,L l){
	P pr=projection(l,c.c);
	P e=(l[1]-l[0])/abs(l[1]-l[0]);
	double t=sqrt(c.r*c.r-norm(pr-c.c));
	P a=pr+t*e;
	P b=pr-t*e;
	if(b<a)swap(a,b);
	return L(a,b);
}
L crosspointCS(C c,L l){
	if(intersectCS(c,l)==2)return crosspointCL(c,l);
	L ret=crosspointCL(c,l);
	if(dot(l[0]-ret[0],l[1]-ret[0])<0)ret[1]=ret[0];
	else ret[0]=ret[1];
	return ret;
}
L crosspointCC(C a,C b){
	P tmp=b.c-a.c;
	double d=abs(tmp);
	double q=acos((a.r*a.r+d*d-b.r*b.r)/(2*a.r*d));
	double t=arg(tmp);//atan(tmp.imag()/tmp.real());
	P p1=a.c+polar(a.r,t+q);
	P p2=a.c+polar(a.r,t-q);
	if(p2<p1)swap(p1,p2);
	return L(p1,p2);
}
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]);
  if (abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
  return m[0] + B / A * (m[1] - m[0]);
}
double area(const G &g){
    double S =0;
    for(int i =0;i <g.size();i++){
        S +=(cross(g[i],g[(i+1)%g.size()]));
    }
    return abs(S/2.0);
}
bool isconvex(const G &g){
	int n=g.size();
	rep(i,n)if(ccw(g[(i+n-1)%n],g[i%n],g[(i+1)%n])==-1)return false;
	return true;
}
int inconvex(const G& g, const P& p) {
	bool in = false;
	int n=g.size();
	rep(i,n){
		P a=g[i%n]-p;
		P b=g[(i+1)%n]-p;
		if(imag(a)>imag(b))swap(a, b);
		if(imag(a)<=0&&0<imag(b))if(cross(a,b)<0)in=!in;
		if(cross(a,b)==0&&dot(a,b)<=0)return 1;//ON
	}
	return in?2:0;//IN : OUT;
}
G convex_hull(G &ps) {
    int n=ps.size(),k=0;
	sort(ps.begin(), ps.end());
	G ch(2*n);
	for(int i=0;i<n;ch[k++]=ps[i++])//lower-hull
		while(k>=2&&ccw(ch[k-2],ch[k-1],ps[i])==-1)--k;//<=0  ->  ==-1
	for(int i=n-2,t=k+1;i>=0;ch[k++]=ps[i--])//upper-hull
		while(k>=t&&ccw(ch[k-2],ch[k-1],ps[i])==-1)--k;//
	ch.resize(k-1);
	return ch;
}
double convex_diameter(const G &pt) {
  const int n = pt.size();
  int is = 0, js = 0;
  for (int i = 1; i < n; ++i) {
    if (imag(pt[i]) > imag(pt[is])) is = i;
    if (imag(pt[i]) < imag(pt[js])) js = i;
  }
  double maxd = norm(pt[is]-pt[js]);

  int i, maxi, j, maxj;
  i = maxi = is;
  j = maxj = js;
  do {
    if (cross(diff(pt,i), diff(pt,j)) >= 0) j = (j+1) % n;
    else i = (i+1) % n;
    if (norm(pt[i]-pt[j]) > maxd) {
      maxd = norm(pt[i]-pt[j]);
      maxi = i; maxj = j;
    }
  } while (i != is || j != js);
  return sqrt(maxd); /* farthest pair is (maxi, maxj). */
}//convex_diameter(g)
G convex_cut(const G& g, const L& l) {
  G Q;
  for (int i = 0; i < g.size(); ++i) {
    P a= curr(g, i), b= next(g, i);
    if (ccw(l[0], l[1], a) != -1) Q.push_back(a);
    if (ccw(l[0], l[1], a)*ccw(l[0], l[1], b) < 0)
      Q.push_back(crosspointLL(L(a,b), l));
  }
  return Q;
}
P turn(P p,double t){
	return p*exp(P(.0,t*PI/180.0));
}
P turn2(P p,double t){
	return p*exp(P(.0,t));
}
vector<L> tangentCC(C a,C b){
	if(a.r<b.r)swap(a,b);
	double d=abs(a.c-b.c);
	vector<L>l;
	if(d<EPS)return l;
	if(a.r+b.r<d-EPS){//hanareteiru
		double t=acos((a.r+b.r)/d);
		t=t*180/PI;
		l.pb(L(a.c+turn(a.r/d*(b.c-a.c),t),b.c+turn(b.r/d*(a.c-b.c),t)));
		l.pb(L(a.c+turn(a.r/d*(b.c-a.c),-t),b.c+turn(b.r/d*(a.c-b.c),-t)));
	}else if(a.r+b.r<d+EPS){//kuttuiteiru soto
		P p=a.c+a.r/d*(b.c-a.c);
		l.pb(L(p,p+turn(b.c-a.c,90)));
	}
	if(abs(a.r-b.r)<d-EPS){//majiwatteiru
		double t1=acos((a.r-b.r)/d);
		t1=t1*180/PI;
		double t2=180-t1;
		l.pb(L(a.c+turn(a.r/d*(b.c-a.c),t1),b.c+turn(b.r/d*(a.c-b.c),-t2)));
		l.pb(L(a.c+turn(a.r/d*(b.c-a.c),-t1),b.c+turn(b.r/d*(a.c-b.c),t2)));
	}else if(abs(a.r-b.r)<d+EPS){//kuttuiteiru uti
		P p=a.c+a.r/d*(b.c-a.c);
		l.pb(L(p,p+turn(b.c-a.c,90)));
	}
	return l;
}
void printL(const L &out){
	printf("%.9f %.9f %.9f %.9f\n",out[0].real(),out[0].imag(),out[1].real(),out[1].imag());
}
C CIN(){
	P p=pin();
	double r;
	cin>>r;
	return C(p,r);
}
bool para(L a,L b){
	return (abs(cross(a[1]-a[0],b[1]-b[0]))<EPS);
}
int main(){
	int n;
	while(cin>>n,n){
		vector<C>c;
		rep(i,n){
			double a,b,d;
			cin>>a>>b>>d;
			c.pb(C(P(a,b),d));
		}
		vector<C>tmp;
		rep(i,n){
			bool h=true;
			rep(j,n)if(i!=j&&abs(c[i].c-c[j].c)<c[j].r-c[i].r)
				h=false;
			if(h)tmp.pb(c[i]);
		}
		c=tmp;
		n=c.size();
		double out=0;
		rep(i,n){
			G g;
			rep(j,n)if(i!=j&&abs(c[i].c-c[j].c)<c[i].r+c[j].r){
				L l=crosspointCC(c[i],c[j]);
				g.pb(l[0]);
				if(l[0]!=l[1])g.pb(l[1]);
			}
			if(g.size()==0){
				out+=2*PI*c[i].r;
				continue;
			}
			rep(j,g.size()-1)rep(k,g.size()-j-1)if(arg(g[k]-c[i].c)>arg(g[k+1]-c[i].c)){
				swap(g[k+1],g[k]);
			}
			rep(j,g.size()){
				double t=arg(g[(j+1)%g.size()]-c[i].c)+arg(g[j]-c[i].c);
				P p=c[i].c+turn2(P(c[i].r,0),t/2+(j==g.size()-1?PI:0));
				bool h=true;
				rep(k,n)if(i!=k&&abs(c[k].c-p)<c[k].r){
					h=false;
					break;
				}
				t=abs(arg(g[(j+1)%g.size()]-c[i].c)-arg(g[j]-c[i].c));
				if(j==g.size()-1)t=2*PI-t;
				if(h)out+=2*c[i].r*t/2;
//				cout<<i<<" "<<j<<" "<<h<<endl;
			}
		}
		printf("%.9f\n",out);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 1364
final_rank: 6

code_snippet: #include<iostream>
#include<vector>
#include<complex>
#include<algorithm>

using namespace std;

typedef complex<double> P;
const double PI=acos(0)*2;

double normalize(double d,double M=2*PI){
  return fmod(fmod(d,M)+M,M);
}

bool contains(P a,double ra,P b,double rb=0){
  return abs(a-b)+rb<ra+1e-9;
}
  
//circle,circle
vector<P> intersection(P a,double ra,P b,double rb){
  double c=abs(b-a);
  double costheta=-(rb*rb-ra*ra-c*c)/2/ra/c;
  if(-1<=costheta&&costheta<=1){
    double theta=acos(costheta);
    double ang=arg(b-a);
    return {a+polar(ra,ang+theta),a+polar(ra,ang-theta)};
  }else{
    return {};
  }
}


int main(){
  for(int n;cin>>n,n;){
    P p[100];
    double r[100];
    for(int i=0;i<n;i++){
      double x,y;
      cin>>x>>y>>r[i];
      p[i]=P(x,y);
    }
    double ans=0;
    for(int i=0;i<n;i++){
      vector<double> angs;
      //      cout<<"---"<<i<<endl;
      for(int j=0;j<n;j++){
	if(i!=j){
	  if(contains(p[j],r[j],p[i],r[i]))goto next;
	  auto is=intersection(p[i],r[i],p[j],r[j]);
	  for(auto e:is){
	    angs.push_back(arg(e-p[i]));
	  }
	}
      }
      {
	sort(begin(angs),end(angs));
	angs.erase(unique(begin(angs),end(angs)),end(angs));
	double c=r[i]*4*acos(0);
	if(angs.size()<2){
	  ans+=c;
	}else{
	  for(int j=0;j<angs.size();j++){
	    double rng=normalize(angs[(j+1)%angs.size()]-angs[j]);
	    P m=p[i]+polar(r[i],angs[j]+rng/2);
	    bool f=false;
	    for(int k=0;k<n;k++){
	      f|=i!=k&&contains(p[k],r[k],m);
	    }
	    if(!f){
	      ans+=rng*r[i];
	    }
	  }
	}
      }
    next:
      ;
    }
    cout.precision(9);
    cout<<fixed<<ans<<endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 1396
final_rank: 9

code_snippet: #include<cstdio>
#include<complex>
#include<vector>
#include<algorithm>
#include<cmath>
#include<map>

#define EPS (1e-8)
#define EQ(a,b) (abs((a)-(b)) < EPS)
#define fs first
#define sc second
#define pb push_back
#define sz size()
#define all(a) (a).begin(),(a).end()
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)

using namespace std;

typedef complex<double> P;
typedef pair<P,P> L;
typedef pair<P,double> C;

const double PI = acos(-1);

P unit(P p){return p / abs(p);}
double dot(P x,P y){return real(conj(x)*y);}
double cross(P x,P y){return imag(conj(x)*y);}

P rotate(P v,double s){
  return P(real(v)*cos(s) - imag(v)*sin(s), real(v)*sin(s) + imag(v)*cos(s) );
}

double arg(P a,P b,P c){return acos(dot(b-a,c-a)/(abs(b-a)*abs(c-a)));}
double arg(double a,double b,double c){return acos( (b*b+c*c-a*a)/(2*b*c) );}

bool in_cir(C c,P x){return (abs(x-c.fs) +EPS < c.sc);}
bool on_cir(C c,P x){return EQ(abs(x-c.fs),c.sc);}

int cpr(C a,C b){
  double d = abs(a.fs-b.fs);
  if(a.sc+b.sc + EPS < d)return -1;
  if(b.sc+d + EPS < a.sc)return 1;
  if(a.sc+d + EPS < b.sc)return 2;
  if(abs(a.sc+b.sc - d) < EPS)return -3;
  if(abs(b.sc+d - a.sc) < EPS)return 3;
  if(abs(a.sc+d - b.sc) < EPS)return 4;
  return 0;
}

vector<P> cp_cir_to_cir(C a, C b){
  vector<P> v;
  int pos = cpr(a,b);
  if(pos==0){
    double s = arg(b.sc,abs(b.fs-a.fs),a.sc);
    P x = a.sc * unit(b.fs - a.fs);
    v.pb(a.fs + rotate(x,s));
    v.pb(a.fs + rotate(x,-s));
  }else if(abs(pos) >= 3){
    v.pb(a.fs + a.sc * unit(b.fs-a.fs));
  }
  return v;
}

double angle(P p, C c){
  P O = c.fs, A = P(c.fs.real(),c.fs.imag()+c.sc), B = p;
  double res = arg(O,A,B);
  if(cross(A-O,B-O)<-EPS)res = 2*PI-res;
  return res;
}

int n;
C c[110];
double x,y,r;

int main(){
  while(scanf("%d",&n),n){
    rep(i,n){
      scanf("%lf%lf%lf",&x,&y,&r);
      c[i] = C(P(x,y),r);
    }

    vector<double> cp_list[110];
    rep(i,n){
      FOR(j,i+1,n){
	vector<P> p = cp_cir_to_cir(c[i],c[j]);
	if((int)p.sz==2){
	  rep(k,2)cp_list[i].pb(angle(p[k],c[i]));
	  rep(k,2)cp_list[j].pb(angle(p[k],c[j]));
	}
      }
    }

    rep(i,n){
      sort(all(cp_list[i]));
      rep(j,(int)cp_list[i].sz-1){
	if(EQ(cp_list[i][j],cp_list[i][j+1])){
	  cp_list[i].erase(cp_list[i].begin()+j);
	  j--;
	}
      }
    }

    double ans = 0;
    rep(i,n){
      if(cp_list[i].empty()){
	bool f = true;
	rep(j,n){
	  if(i==j)continue;
	  if(in_cir(c[j],c[i].fs) && c[i].sc < c[j].sc)f = false;
	}
	if(f)ans += 2*PI*c[i].sc;
      }else{
	rep(j,cp_list[i].sz){
	  double s;
	  if(j+1<(int)cp_list[i].sz)s = (cp_list[i][j]+cp_list[i][j+1])/2;
	  else s = (cp_list[i][j]+cp_list[i][0]+2*PI)/2;

	  P p = rotate(P(0,c[i].sc),s) + c[i].fs;
	  bool f = true;
	  rep(k,n){
	    if(i==k)continue;
	    if(in_cir(c[k],p))f = false;
	  }
	  double seta = cp_list[i][(j+1)%cp_list[i].sz]-cp_list[i][j];
	  if(seta<0)seta += 2*PI;
	  if(f)ans += seta*c[i].sc;
	}
      }
    }
    printf("%.9lf\n",ans);
  }
}
accuracy: 1
time_ms: 10
memory_kb: 1188
final_rank: 4

code_snippet: #include<iostream>
#include<complex>
#include<vector>
#include<algorithm>
#include<cmath>
#include<map>
#include<iomanip>

#define EPS (1e-8)
#define EQ(a,b) (abs((a)-(b)) < EPS)
#define fs first
#define sc second
#define pb push_back
#define sz size()
#define all(a) (a).begin(),(a).end()
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)

using namespace std;

typedef complex<double> P;
typedef pair<P,P> L;
typedef pair<P,double> C;

const double PI = acos(-1);

P unit(P p){return p / abs(p);}
double dot(P x,P y){return real(conj(x)*y);}
double cross(P x,P y){return imag(conj(x)*y);}

P rotate(P v,double s){
  return P(real(v)*cos(s) - imag(v)*sin(s), real(v)*sin(s) + imag(v)*cos(s) );
}

double arg(P a,P b,P c){return acos(dot(b-a,c-a)/(abs(b-a)*abs(c-a)));}
double arg(double a,double b,double c){return acos( (b*b+c*c-a*a)/(2*b*c) );}

bool in_cir(C c,P x){return (abs(x-c.fs) +EPS < c.sc);}
bool on_cir(C c,P x){return EQ(abs(x-c.fs),c.sc);}

int cpr(C a,C b){
  double d = abs(a.fs-b.fs);
  if(a.sc+b.sc + EPS < d)return -1;
  if(b.sc+d + EPS < a.sc)return 1;
  if(a.sc+d + EPS < b.sc)return 2;
  if(abs(a.sc+b.sc - d) < EPS)return -3;
  if(abs(b.sc+d - a.sc) < EPS)return 3;
  if(abs(a.sc+d - b.sc) < EPS)return 4;
  return 0;
}

vector<P> cp_cir_to_cir(C a, C b){
  vector<P> v;
  int pos = cpr(a,b);
  if(pos==0){
    double s = arg(b.sc,abs(b.fs-a.fs),a.sc);
    P x = a.sc * unit(b.fs - a.fs);
    v.pb(a.fs + rotate(x,s));
    v.pb(a.fs + rotate(x,-s));
  }else if(abs(pos) >= 3){
    v.pb(a.fs + a.sc * unit(b.fs-a.fs));
  }
  return v;
}

double angle(P p, C c){
  P O = c.fs, A = P(c.fs.real(),c.fs.imag()+c.sc), B = p;
  double res = arg(O,A,B);
  if(cross(A-O,B-O)<-EPS)res = 2*PI-res;
  return res;
}

int n;
C c[110];
double x,y,r;

int main(){
  while(cin>>n,n){
    rep(i,n){
      cin >> x >> y >> r;
      c[i] = C(P(x,y),r);
    }

    vector<double> cp_list[110];
    rep(i,n){
      FOR(j,i+1,n){
	vector<P> p = cp_cir_to_cir(c[i],c[j]);
	if((int)p.sz==2){
	  rep(k,2)cp_list[i].pb(angle(p[k],c[i]));
	  rep(k,2)cp_list[j].pb(angle(p[k],c[j]));
	}
      }
    }

    rep(i,n){
      sort(all(cp_list[i]));
      rep(j,(int)cp_list[i].sz-1){
	if(EQ(cp_list[i][j],cp_list[i][j+1])){
	  cp_list[i].erase(cp_list[i].begin()+j);
	  j--;
	}
      }
    }

    double ans = 0;
    rep(i,n){
      if(cp_list[i].empty()){
	bool f = true;
	rep(j,n){
	  if(i==j)continue;
	  if(in_cir(c[j],c[i].fs) && c[i].sc < c[j].sc)f = false;
	}
	if(f)ans += 2*PI*c[i].sc;
      }else{
	rep(j,cp_list[i].sz){
	  double s;
	  if(j+1<(int)cp_list[i].sz)s = (cp_list[i][j]+cp_list[i][j+1])/2;
	  else s = (cp_list[i][j]+cp_list[i][0]+2*PI)/2;

	  P p = rotate(P(0,c[i].sc),s) + c[i].fs;
	  bool f = true;
	  rep(k,n){
	    if(i==k)continue;
	    if(in_cir(c[k],p))f = false;
	  }
	  double seta = cp_list[i][(j+1)%cp_list[i].sz]-cp_list[i][j];
	  if(seta<0)seta += 2*PI;
	  if(f)ans += seta*c[i].sc;
	}
      }
    }
    cout << fixed << setprecision(9) << ans << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 1388
final_rank: 7

code_snippet: #include<iostream>
#include<complex>
#include<vector>
#include<algorithm>
#include<cmath>
#include<map>
#include<list>
#include<iomanip>

#define EPS (1e-8)
#define EQ(a,b) (abs((a)-(b)) < EPS)
#define fs first
#define sc second
#define pb push_back
#define sz size()
#define all(a) (a).begin(),(a).end()
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)

using namespace std;

typedef complex<double> P;
typedef pair<P,P> L;
typedef pair<P,double> C;

const double PI = acos(-1);

//for vector
P unit(P p){return p / abs(p);}

pair<P,P> norm(P p){return make_pair(p*P(0,1),p*P(0,-1));}

double dot(P x,P y){return real(conj(x)*y);}

double cross(P x,P y){return imag(conj(x)*y);}

//rotate a point counter-clockwise on the origin
P rotate(P v,double s){
  return P(real(v)*cos(s) - imag(v)*sin(s), real(v)*sin(s) + imag(v)*cos(s) );
}

//return seta A
double arg(P a,P b,P c){return acos(dot(b-a,c-a)/(abs(b-a)*abs(c-a)));}
double arg(double a,double b,double c){return acos( (b*b+c*c-a*a)/(2*b*c) );}

//for circle

bool in_cir(C c,P x){return (abs(x-c.fs) +EPS < c.sc);}
bool on_cir(C c,P x){return EQ(abs(x-c.fs),c.sc);}

//circle position relation
int cpr(C a,C b){
  double d = abs(a.fs-b.fs);
  if(a.sc+b.sc + EPS < d)return -1;      //no cross point (outside)
  if(b.sc+d + EPS < a.sc)return 1;       //no cross point (inside,B in A)
  if(a.sc+d + EPS < b.sc)return 2;       //no cross point (inside,A in B)
  if(abs(a.sc+b.sc - d) < EPS)return -3; //one cross point (outside)
  if(abs(b.sc+d - a.sc) < EPS)return 3;  //one cross point (inside,B in A)
  if(abs(a.sc+d - b.sc) < EPS)return 4;  //one cross point (inside,A in B)
  return 0;                              //two cross point
}

vector<P> cp_cir_to_cir(C a, C b){
  vector<P> v;
  int pos = cpr(a,b);
  if(pos==0){
    double s = arg(b.sc,abs(b.fs-a.fs),a.sc);
    P x = a.sc * unit(b.fs - a.fs);
    v.pb(a.fs + rotate(x,s));
    v.pb(a.fs + rotate(x,-s));
  }else if(abs(pos) >= 3){
    v.pb(a.fs + a.sc * unit(b.fs-a.fs));
  }
  return v;
}

double angle(P p, C c){
  P O = c.fs, A = P(c.fs.real(),c.fs.imag()+c.sc), B = p;
  double res = arg(O,A,B);
  if(cross(A-O,B-O)<-EPS)res = 2*PI-res;
  return res;
}

int n;
C c[110];
double x,y,r;

int main(){
  while(cin>>n,n){
    rep(i,n){
      cin >> x >> y >> r;
      c[i] = C(P(x,y),r);
    }

    vector<double> cp_list[110];
    rep(i,n){
      FOR(j,i+1,n){
	vector<P> p = cp_cir_to_cir(c[i],c[j]);
	if((int)p.sz==2){
	  rep(k,2)cp_list[i].pb(angle(p[k],c[i]));
	  rep(k,2)cp_list[j].pb(angle(p[k],c[j]));
	}
      }
    }

    rep(i,n){
      sort(all(cp_list[i]));
      rep(j,(int)cp_list[i].sz-1){
	if(EQ(cp_list[i][j],cp_list[i][j+1])){
	  cp_list[i].erase(cp_list[i].begin()+j);
	  j--;
	}
      }
    }

    double ans = 0;
    rep(i,n){
      if(cp_list[i].empty()){
	bool f = true;
	rep(j,n){
	  if(i==j)continue;
	  if(in_cir(c[j],c[i].fs) && c[i].sc < c[j].sc)f = false;
	}
	if(f)ans += 2*PI*c[i].sc;
      }else{
	rep(j,cp_list[i].sz){
	  double s;
	  if(j+1<(int)cp_list[i].sz)s = (cp_list[i][j]+cp_list[i][j+1])/2;
	  else s = (cp_list[i][j]+cp_list[i][0]+2*PI)/2;

	  P p = rotate(P(0,c[i].sc),s) + c[i].fs;
	  bool f = true;
	  rep(k,n){
	    if(i==k)continue;
	    if(in_cir(c[k],p))f = false;
	  }
	  double seta = cp_list[i][(j+1)%cp_list[i].sz]-cp_list[i][j];
	  if(seta<0)seta += 2*PI;
	  if(f)ans += seta*c[i].sc;
	}
      }
    }
    cout << fixed << setprecision(10) << ans << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 1388
final_rank: 7

code_snippet: #include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
double x[100],y[100],r[100];
int size[100];
pair<double,int> e[100][40000];
int d[100];
double DIST[100][100];
inline double HYP(double a,double b){
	return sqrt(a*a+b*b);
}
double PI=3.14159265359;
double EPS=1e-5;
int main(){
	int a;
	while(scanf("%d",&a),a){
		for(int i=0;i<a;i++)scanf("%lf%lf%lf",x+i,y+i,r+i);
		for(int i=0;i<a;i++){
			size[i]=0;
			d[i]=1;
		}
		for(int i=0;i<a;i++)
			for(int j=0;j<a;j++)
				DIST[i][j]=HYP(x[i]-x[j],y[i]-y[j]);
		for(int i=0;i<a;i++){
			for(int j=0;j<a;j++){
				if(i==j)continue;
				if(DIST[i][j]<(double)r[j]-r[i]+EPS)d[i]=0;
				else if(DIST[i][j]<(double)r[i]-r[j]+EPS);
				else if(DIST[i][j]+EPS<(double)r[i]+r[j]){
					double c=atan2(y[j]-y[i],x[j]-x[i]);
					double p=acos(0.5*(DIST[i][j]*DIST[i][j]+r[i]*r[i]-r[j]*r[j])/DIST[i][j]/r[i]);
					double t1=c-p;
					double t2=c+p;
					if(t2<0){
						t1+=PI*2;
						t2+=PI*2;
					}
					if(t2>PI*2){
						t1-=PI*2;
						t2-=PI*2;
					}
					if(t1<0){
						e[i][size[i]++]=make_pair(t1+PI*2,1);
						e[i][size[i]++]=make_pair(PI*2,2);
						t1=0;
					}
					e[i][size[i]++]=(make_pair(t1,1));
					e[i][size[i]++]=(make_pair(t2,2));
				}
			}
		}
		for(int i=0;i<a;i++)std::sort(e[i],e[i]+size[i]);
		double ret=0;
		for(int i=0;i<a;i++){
			if(d[i]){
				int now=0;
				double at=0;
				for(int j=0;j<size[i];j++){
					if(!now)ret+=(e[i][j].first-at)*r[i];
					if(e[i][j].second==1)now++;
					else now--;
					at=e[i][j].first;
				}
				ret+=(PI*2-at)*r[i];
			}
		}
		printf("%.9f\n",ret);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 63752
final_rank: 13

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

const double EPS = 1.0e-10;
const double PI = acos(-1.0);

class Point
{
public:
    double y, x;
    Point(){
        y = x = 0.0;
    }
    Point(double y0, double x0){
        y = y0;
        x = x0;
    }
    Point(double theta){
        y = sin(theta);
        x = cos(theta);
    }
    Point operator+(const Point& p) const{
        return Point(y + p.y, x + p.x);
    }
    Point operator-(const Point& p) const{
        return Point(y - p.y, x - p.x);
    }
    Point operator*(double a) const{
        return Point(y * a, x * a);
    }
    Point operator/(double a) const{
        return Point(y / a, x / a);
    }
    double length() const{
        return sqrt(y * y + x * x);
    }
    double dist(const Point& p) const{
        return sqrt(pow(y - p.y, 2) + pow(x - p.x, 2));
    }
    double dot(const Point& p) const{
        return y * p.y + x * p.x; // |a|*|b|*cos慮
    }
    double cross(const Point& p) const{
        return x * p.y - y * p.x; // |a|*|b|*sin慮
    }
    double angle() const{
        return atan2(y, x);
    }
};

int circlesIntersection(const Point& p1, double r1, const Point& p2, double r2, vector<Point>& intersection)
{
    double y = p2.y - p1.y;
    double x = p2.x - p1.x;
    double a = (y*y + x*x + r1*r1 - r2*r2) / 2;
    double b = (y*y + x*x) * r1*r1 - a*a;

    if(y*y + x*x < EPS || b < -EPS){
        intersection.resize(0);
        return 0;
    }
    if(b < EPS){
        intersection.assign(1, Point(y, x) * (a / (y*y + x*x)) + p1);
        return 1;
    }

    intersection.assign(2, Point(x, -y) * sqrt(b));
    intersection[1] = intersection[1] * -1;
    for(int i=0; i<2; ++i)
        intersection[i] = (intersection[i] + Point(y, x) * a) / (y*y + x*x) + p1;
    return 2;
}

int main()
{
    for(;;){
        int n;
        cin >> n;
        if(n == 0)
            return 0;

        vector<Point> p(n);
        vector<double> r(n);
        for(int i=0; i<n; ++i)
            cin >> p[i].x >> p[i].y >> r[i];

        double ret = 0.0;
        for(int i=0; i<n; ++i){
            vector<double> theta;
            for(int j=0; j<n; ++j){
                if(i == j)
                    continue;

                vector<Point> q;
                circlesIntersection(p[i], r[i], p[j], r[j], q);
                for(unsigned k=0; k<q.size(); ++k)
                    theta.push_back((q[k] - p[i]).angle());
            }

            if(theta.empty()){
                Point q = p[i] + Point(r[i], 0);
                bool ok = true;
                for(int j=0; j<n; ++j){
                    if(i != j && q.dist(p[j]) < r[j])
                        ok = false;
                }
                if(ok)
                    ret += r[i] * 2 * PI;
            }else{
                sort(theta.begin(), theta.end());
                theta.push_back(theta[0] + 2 * PI);
                for(unsigned j=1; j<theta.size(); ++j){
                    double a = (theta[j] + theta[j-1]) / 2;
                    Point q = p[i] + Point(a) * r[i];
                    bool ok = true;
                    for(int k=0; k<n; ++k){
                        if(p[k].dist(q) < r[k] - EPS)
                            ok = false;
                    }
                    if(ok)
                        ret += r[i] * (theta[j] - theta[j-1]);
                }
            }
        }

        printf("%.10f\n", ret);
    }
}
accuracy: 1
time_ms: 10
memory_kb: 1332
final_rank: 5

code_snippet: #include<cstdio>
#include<vector>
#include<complex>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

typedef complex<double> Point;

const double EPS=1e-9;
const double PI=acos(-1);

class Line:public vector<Point>{
public:
	Line(const Point &a,const Point &b){ push_back(a), push_back(b); }
};

class Segment:public Line{
public:
	Segment(const Point &a,const Point &b):Line(a,b){}
};

class Circle{
public:
	Point c;
	double r;
	Circle(){}
	Circle(const Point &C,double R):c(C),r(R){}
};

inline double dot(const Point &a,const Point &b){
	return a.real()*b.real()+a.imag()*b.imag();
}

inline double cross(const Point &a,const Point &b){
	return a.real()*b.imag()-a.imag()*b.real();
}

inline void calc_abc(const Line &l,double &a,double &b,double &c){
	a=l[0].imag()-l[1].imag();
	b=l[1].real()-l[0].real();
	c=cross(l[0],l[1]);
}

Point PerpFoot(const Point &p,const Line &l){
	double a,b,c;
	calc_abc(l,a,b,c);
	Point v(a,b);
	return p-(dot(p,v)+c)*v/norm(v);
}

bool cover(const Segment &s,const Point &p){
	return dot(s[0]-p,s[1]-p)<EPS;
}

bool cover(const Circle &c,const Point &p){
	return abs(p-c.c)<c.r+EPS;
}

bool cover(const Circle &c1,const Circle &c2){
	return abs(c1.c-c2.c)+c2.r<c1.r+EPS;
}

int intersect(const Circle &c,const Line &l,Point &p,Point &q){
	Point m=PerpFoot(c.c,l);
	double d2=norm(c.c-m);
	if(c.r*c.r+EPS<d2) return 0;
	else if(abs(c.r*c.r-d2)<EPS){
		p=q=m;
		return 1;
	}
	else{
		Point v;
		double n0=norm(l[0]-m),n1=norm(l[1]-m);
		if(n0<n1) v=l[1]-m, n0=n1;
		else      v=l[0]-m;
		v*=sqrt((c.r*c.r-d2)/n0);
		p=m+v, q=m-v;
		return 2;
	}
}

int intersect(const Circle &c,const Segment &s,Point &p,Point &q){
	Point pp,qq;
	int n=intersect(c,Line(s),pp,qq);
	if(n==0) return 0;
	else if(n==1){
		if(cover(s,pp)){
			p=q=pp;
			return 1;
		}
		return 0;
	}
	else{
		bool bp=cover(s,pp),bq=cover(s,qq);
		if(bp&&bq){
			p=pp, q=qq;
			return 2;
		}
		if(bp||bq){
			p=q=(bp?pp:qq);
			return 1;
		}
		return 0;
	}
}

int intersect(const Circle &c1,const Circle &c2,Point &p,Point &q){
	double d2=norm(c1.c-c2.c);
	if(d2<EPS && abs(c1.r-c2.r)<EPS) return -1; // c1==c2
	if((c1.r+c2.r)*(c1.r+c2.r)+EPS<d2 || d2+EPS<(c1.r-c2.r)*(c1.r-c2.r)) return 0;

	double d=sqrt(d2);
	if(abs(c1.r+c2.r-d)<EPS){
		intersect(c1,Segment(c1.c,c2.c),p,q);
		return 1;
	}

	double a=(c1.r*c1.r-c2.r*c2.r+d2)/(2*d);
	double h=sqrt(c1.r*c1.r-a*a);
	p=q=c1.c+a/d*(c2.c-c1.c);
	Point tmp=h*(c2.c-c1.c)/d;
	p+=tmp*Point(0,-1);
	q+=tmp*Point(0,+1);
	return 2;
}

Point c_cmp;
bool cmp_arg(const Point &p,const Point &q){ return arg(p-c_cmp)<arg(q-c_cmp); }

int main(){
	for(int n;scanf("%d",&n),n;){
		Circle C[100];
		rep(i,n){
			double x,y; scanf("%lf%lf%lf",&x,&y,&C[i].r);
			C[i].c=Point(x,y);
		}

		vector<Point> P[100];
		rep(j,n) rep(i,j) {
			Point p,q;
			if(intersect(C[i],C[j],p,q)==2){
				P[i].push_back(p); P[i].push_back(q);
				P[j].push_back(p); P[j].push_back(q);
			}
		}

		double ans=0;
		rep(i,n){
			bool cov=false;
			rep(j,n) if(j!=i && cover(C[j],C[i])) cov=true;
			if(cov) continue;

			int m=P[i].size();
			c_cmp=C[i].c;
			sort(P[i].begin(),P[i].end(),cmp_arg);

			if(m==0) ans+=2*PI*C[i].r;

			rep(j,m){
				const Point &a=P[i][j],&b=P[i][(j+1)%m];
				double theta=arg(b-C[i].c)-arg(a-C[i].c);
				if(theta<0) theta+=2*PI;
				Point c=C[i].c+(a-C[i].c)*exp(Point(0,theta/2));

				bool ok=true;
				rep(k,n) if(k!=i && cover(C[k],c)) ok=false;
				if(ok) ans+=C[i].r*theta;
			}
		}

		printf("%.9f\n",ans);
	}

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

code_snippet: #include<iostream>
#include<cstdio>
#include<complex>
#include<vector>
#include<algorithm>

#define EPS 1.0e-12
#define PI acos(-1.0)

using namespace std;

typedef double elem;
typedef complex<elem> point, vec;

inline elem sq(elem a){ return a * a; }
inline elem dist(const point &p1, const point &p2){ return abs(p2-p1); }
inline bool eq(elem a, elem b){ return abs(a-b)<EPS; }
inline bool eqv(const vec &a, const vec &b){ return eq( a.real(), b.real() ) && eq( a.imag(), b.imag() );  }
inline elem dot(const vec &a, const vec &b){ return a.real() * b.real() + a.imag() * b.imag(); } 
inline elem cross(const vec &a, const vec &b){ return a.real() * b.imag() - a.imag() * b.real(); }
inline elem rad(const vec &a, const vec &b){ return acos( dot(a,b) / ( abs(a) * abs(b) ) ); }
inline vec uvec(const vec &a){ return a / abs(a); }
inline vec normr(const vec &a){ return a * vec(0,-1); }
inline vec norml(const vec &a){ return a * vec(0,1); }
inline vec unormr(const vec &a){ return uvec( normr( a ) ); }
inline vec unorml(const vec &a){ return uvec( norml( a ) ); }

struct circle{
	elem r; point c;
	elem Perimeter()const{ return 2 * r * PI; }
	bool Inside(const point &p)const{ return dist(p,c) < r; }
	bool Wrap(const circle &t)const{ elem d = dist(c,t.c); return d + t.r <= r; }
};

int CircleCross(const circle &c1, const circle &c2, pair<point,point> &p)
{
	elem d = dist( c1.c, c2.c );
	
	if( eqv( c1.c, c2.c ) && eq( c1.r, c2.r ) ){ /* ñÂÌ~ªêv */ return -1; }
	if( eqv( c1.c, c2.c ) ){ /* S¾¯êvµÄ¢é */ return 0; }
	if( d > c1.r + c2.r ){ /* ~ªÝ¢ÉðíçÈ¢ */ return 0; }

	vec ab = c2.c - c1.c;
	elem k = ( sq( c1.r ) - sq( c2.r ) + sq( d ) ) / ( 2 * sq( d ) );
	point t = k * ab + c1.c;
	elem x = sqrt( sq(c1.r) - sq( d * k ) );

	if( eq( x, 0 ) ){ /* ð_ðêÂ¾¯Â */ p.first = t; return 1;
	}else{ /* ð_ðñÂÂ */
		vec abr = unormr( ab ); vec abl = unorml( ab );
		vec vp1 = x * abr; vec vp2 = x * abl;
		p.first = vp1 + t; p.second = vp2 + t;
		return 2;
	}
}

struct point_on_circle{
	point p;
	circle c; // ð_pª®·é~
};

struct circle_info{
	circle c;
	vector< point_on_circle > cross_points;
};

void center_point( const point_on_circle &p1, const point_on_circle &p2, pair<elem,elem> &p_arc, pair<point,point> &p_center )
{
	vec v1(p1.p - p1.c.c);
	vec v2(p2.p - p2.c.c);

	vec c_p = p1.c.r * uvec( v1 + v2 ) + p1.c.c;
	p_center.first = c_p;
	p_arc.first = p1.c.r * rad( v1, v2 );

	vec c_n = p1.c.r * (-uvec( v1 + v2 ) ) + p1.c.c;
	p_center.second = c_n;
	p_arc.second = p1.c.Perimeter() - p_arc.first;

	if( 0 < cross( v1, v2 ) ){
		swap(p_arc.first, p_arc.second);
		swap(p_center.first, p_center.second);
	}
}

bool PointsClkws(const point_on_circle &p1, const point_on_circle &p2)
{
	vec t(0,1);
	vec v1(p1.p-p1.c.c);
	vec v2(p2.p-p2.c.c);
	elem rad1 = rad( v1, t );
	elem rad2 = rad( v2, t );
	if( cross(v1,t) < 0 )
		rad1 = 2 * PI - rad1;
	if( cross(v2,t) < 0 )
		rad2 = 2 * PI - rad2;

	return rad1 < rad2;
}

int main()
{
	while(true){
		int n;
		elem ans = 0;
		vector<circle_info> vc;
		
		scanf("%d", &n);
		if( n == 0 )
			break;
		
		vc.resize(n);
		for(int i = 0; i < n; ++i){
			double x,y,r;
			scanf("%lf%lf%lf", &x, &y, &r);
			vc[i].c.c = complex<elem>(x,y);
			vc[i].c.r = r;
		}

		// ¼Ì~Éàï³êé~ðí
		for(unsigned int i = 0; i < vc.size(); ++i){
			for(unsigned int j = 0; j < vc.size(); ++j){
				if( i != j ){
					if( vc[j].c.Wrap( vc[i].c ) ){
						vc.erase( vc.begin() + i );
						i = -1;
						break;
					}
				}
			}
		}
		
		// ~¯mÌð_ðßé
		for(unsigned int i = 0; i < vc.size(); ++i){
			for(unsigned int j = 0; j < vc.size(); ++j){
				if( i != j ){
					pair<point,point> p;
					int t = CircleCross( vc[i].c, vc[j].c, p );
					point_on_circle p1, p2;
					
					p1.c = vc[i].c;
					p1.p = p.first;
					p2.c = vc[i].c;
					p2.p = p.second;
					
					if( t <= 1 ){
						continue;
					}else{
						vc[i].cross_points.push_back( p1 );
						vc[i].cross_points.push_back( p2 );
					}
				}
			}
		}

		// d¡·é¤L_ðí
		for(unsigned int i = 0; i < vc.size(); ++i){
			for(unsigned int j = 0; j < vc[i].cross_points.size(); ++j){
				for(unsigned int k = j + 1; k < vc[i].cross_points.size(); ++k){
					if( eqv( vc[i].cross_points[j].p, vc[i].cross_points[k].p ) ){
						vc[i].cross_points.erase( vc[i].cross_points.begin() + k );
						--k;
					}
				}
			}
		}
		
		// ¤L_ðvñèÉ®ñ
		for(unsigned int i = 0; i < vc.size(); ++i){
			sort( vc[i].cross_points.begin(), vc[i].cross_points.end(), PointsClkws );
		}

		// solve
		for(unsigned int i = 0; i < vc.size(); ++i){
			ans += vc[i].c.Perimeter();
			if( vc[i].cross_points.size() > 1 ){
				for(unsigned int j = 0; j < vc[i].cross_points.size(); ++j){
					unsigned int mod = vc[i].cross_points.size();
					pair<elem, elem> p_arc;
					pair<point, point> p_center;
					
					center_point( vc[i].cross_points[j % mod], vc[i].cross_points[(j+1) % mod], p_arc, p_center );

					for(unsigned int k = 0; k < vc.size(); ++k){
						if( i != k ){
							if( vc[k].c.Inside( p_center.first ) ){
								ans -= p_arc.first;
								break;
							}
						}
					}
				}
			}
		}

		printf("%.12lf\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include<iostream>
#include<complex>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
typedef complex<double> P;
#define eps 0

//~ÌSÀWða,b,¼aðr1,r2Æ·éB
//r1Ær2ÌÔÌ£ðßÄ]·èÉæèr1Æ»ÌÓÌÈ·pðßéB
// ÆÍpolarðgÁÄÀWð¶¬·éB
//ñ_ÌÀWðÔ·B
pair<double,double> CC_intersection(P a,P b,double r1,double r2){//~Æ~Ìð_
  double r3 = abs(a-b);
  double theta = acos( (r1*r1 + r3*r3 -r2*r2)/(2*r1*r3) ); 
  return make_pair(theta+arg(b-a),arg(b-a)-theta);
}

bool cmp(const P &a,const P&b){
  return arg(a)<arg(b);
}
class Circle{
public:
  vector<double> data;
};

double solve(int n,P *in,double *r){
  Circle data[n];
  double ret =0;
  rep(i,n){ 
    //data[i].data.push_back(asin(1));data[i].data.push_back(asin(-1));
    data[i].data.push_back(0);data[i].data.push_back(0.1);
    rep(j,n){
      if ( i==j)continue;
      if ( r[i]+r[j] <eps+abs(in[i]-in[j]))continue;
      if ( abs(in[i]-in[j])+r[i] <r[j]+eps||abs(in[i]-in[j])+r[j]<r[i]+eps)continue;
      
      pair<double,double> a=CC_intersection(in[i],in[j],r[i],r[j]);
      data[i].data.push_back(a.first);
      data[i].data.push_back(a.second);
    }
  }
  
  rep(i,n)sort(data[i].data.begin(),data[i].data.end());
  


  rep(i,n){
    int size=data[i].data.size();
    rep(j,size){
      double now = data[i].data[j],nex=data[i].data[(j+1)%size];
      
      double theta = (nex-now)/2+now;
      if (nex-now<0)theta=(acos(-1)*2+nex-now)/2+now;
      
      P mid = polar(r[i],theta)+in[i];
      
      bool flag=true;
      rep(k,n){
	if ( i == k)continue;
	if (abs(in[k]-mid)<eps+r[k]){flag=false;break;}
      }

      double test =nex-now;
      if ( test <0)test=acos(-1)*2+nex-now;
      if ( flag){
	ret+=r[i]*abs(test);
      }
      
    }
  }
  return ret;
}

main(){
  int n;
  while(cin>>n&&n){
    P in[n];double r[n];
    rep(i,n)cin>>in[i].real()>>in[i].imag()>>r[i];
    printf("%.10lf\n",solve(n,in,r));
  }
  return false;
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1

code_snippet: #include<iostream>
#include<cfloat>
#include<cassert>
#include<cmath>
#include<cstdio>
#include<vector>
#include<algorithm>

using namespace std;

#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS )
#define dle(a, b) (equals(a, b) || a < b )
static const double PI = acos(-1);

class Point{
    public:
    double x, y;
    
    Point ( double x = 0, double y = 0): 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 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;
    }
};

typedef Point Vector;

class Segment{
    public:
    Point p1, p2;
    Segment(Point s = Point(), Point t = Point()): p1(s), p2(t){}
};

typedef Segment Line;

static const int CIRCLE_NON = 0;
static const int CIRCLE_OUT = 1;
static const int CIRCLE_IN = 2;
static const int CIRCLE_CROSS = 3;

class Circle{
    public:
    Point c;
    double r;
    Circle(Point c = Point(), double r = 0.0): c(c), r(r){}
};

double norm( Vector a ){ return a.x*a.x + a.y*a.y; }
double abs( Vector a ){ return sqrt(norm(a)); }
Point polar( double a, double r ){ return Point(cos(r)*a, sin(r)*a);}
double getDistance( Vector a, Vector b ){ return abs(a - b); }
double dot( Vector a, Vector b ){ return a.x*b.x + a.y*b.y; }
double cross( Vector a, Vector b ){ return a.x*b.y - a.y*b.x; }

double getAngle(Point p){
    double polar = atan2(p.y, p.x);
    return (dle(0, polar))? polar : 2.0*acos(-1)+polar;
}

int isIntersect(Circle c1, Circle c2){
    double d = abs(c1.c - c2.c);
    if ( c1.r + c2.r < d ) return CIRCLE_NON; // no overlap
    if ( d + c2.r < c1.r ) return CIRCLE_IN;  // c1 includes c2
    if ( d + c1.r < c2.r ) return CIRCLE_OUT;  // c2 includes c1
    return CIRCLE_CROSS;
}

double arg(Vector p){
    return atan2(p.y, p.x);
}

pair<Point, Point> getCrossPoints(Circle c1, Circle c2){
    assert( isIntersect( c1, c2 ) );
    double d = abs(c1.c - c2.c);
    double a = acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
    double t = arg(c2.c - c1.c);
    return make_pair(c1.c+polar(c1.r, t+a), c1.c+polar(c1.r, t-a));
}


Circle C[100];
int n;

void compute(){
    double len = 0.0;

    for ( int i = 0; i < n; i++ ){
	vector<double> angles;
	for ( int j = 0; j < n; j++ ){
	    if ( i == j ) continue;
	    if ( isIntersect(C[i], C[j]) != CIRCLE_CROSS ) continue;
	    pair<Point, Point> pp = getCrossPoints(C[i], C[j]);
	    angles.push_back(getAngle(pp.first - C[i].c));
	    angles.push_back(getAngle(pp.second - C[i].c));
	}
	angles.push_back(0.0);
	angles.push_back(2*PI);

	sort( angles.begin(), angles.end() );

	for ( int a = 1; a < angles.size(); a++ ) {
	    Point m = C[i].c + polar(C[i].r, (angles[a]+angles[a-1])/2.0);
	    bool included = false;
	    for ( int t = 0; t < n; t++ ){
		if ( t == i ) continue;
		if ( dle(getDistance(m, C[t].c), C[t].r) ) included = true;
	    }

	    if ( !included ){
		len += (angles[a] - angles[a-1])*C[i].r;
	    }
	}
    }

    printf("%.12lf\n", len);
}

int main(){
    double x, y, r;
    while( cin >> n  ){
	if ( n == 0 ) break;
	for ( int i = 0; i < n; i++ ){
	    cin >> x >> y >> r; C[i] = Circle( Point(x, y), r);
	}
	compute();
    }
    
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 996
final_rank: 14