#include <bits/stdc++.h>
    using namespace std;
     
    using i64=int64_t;
     
    #define rep(i,x,y) for(i64 i=i64(x),i##_max_for_repmacro=i64(y); i<i##_max_for_repmacro; ++i)
    #define debug(x) #x << "=" << (x)
     
    #ifdef DEBUG
    #define _GLIBCXX_DEBUG
    #define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
    #else
    #define print(x)
    #endif
     
    const int inf=1.01e9;
    const i64 inf64=4.01e18;
    const double eps=1e-9;
     
    template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec){
        os << "[";
        for (const auto &v : vec) {
            os << v << ",";
        }
        os << "]";
        return os;
    }
     
    template<int D,class point> struct kd_tree{
        point p;
        int axis,val;
        kd_tree<D,point>* left,*right;
        kd_tree(int axis_=0):left(NULL),right(NULL),axis(axis_){};
        kd_tree(vector<pair<point,int>> points,int axis_=0):left(NULL),right(NULL),axis(axis_){ assert(points.size()); build(points,0,points.size()); }
        ~kd_tree(){ delete left; delete right; }
        kd_tree<D,point>* build(vector<pair<point,int>> &points,int l,int r){
            int m=(l+r)/2;
            nth_element(points.begin()+l,points.begin()+m,points.begin()+r,[&](const pair<point,int>& p,const pair<point,int>& q){ return p.first[axis]<q.first[axis]; });
            p=points[m].first;
            val=points[m].second;
            if(l<m){
                left=new kd_tree<D,point>((axis+1)%D);
                left->build(points,l,m);
            }
            if(m+1<r){
                right=new kd_tree<D,point>((axis+1)%D);
                right->build(points,m+1,r);
            }
            return this;
        }
        //例えば,同じ点が大量にinsertされると右の子ばかり増えてしまう.そのようなときは適当なタイミングで全体をリビルドしたほうがよいかも.
        kd_tree<D,point>* insert(const point& q){
            if(q[axis]<p[axis]){
                if(left==NULL){
                    left=new kd_tree<D,point>({q},(axis+1)%D);
                    return left;
                }else return left->insert(q);
            }else{
                if(right==NULL){
                    right=new kd_tree<D,point>({q},(axis+1)%D);
                    return right;
                }else return right->insert(q);
            }
        }
        //未検証.多分遅い(O(n))のでerasedタグを付けて置いて,erasedが一定以上増えたら全体をbuildするようにした方が良いかも.
        void erase(const point& q){
            kd_tree<D,point>* tree=nearest_neighbor(q);
            vector<point> points=tree->collect();
            points.erase(points.rbegin());
            delete tree->left;
            delete tree->right;
            tree->build(points,0,points.size());
        }
        //未検証
        vector<point> collect()const{
            vector<point> points;
            if(left!=NULL){
                vector<point> left_points=left->collect();
                points.insert(points.end(),left_points.begin(),left_points.end());
            }
            if(right!=NULL){
                vector<point> right_points=right->collect();
                points.insert(points.end(),right_points.begin(),right_points.end());
            }
            points.push_back(p);
            return points;
        };
        const kd_tree<D,point>* nearest_neighbor(const point& q)const{ //const外した方が良いかも
            const kd_tree<D,point>* res=this;
            long double mind=1e130;
            auto dist=[&](const point& p,const point& q){
                long double d=0;
                for(int i=0; i<D; ++i) d+=(p[i]-q[i])*(p[i]-q[i]);
                return d;
            };
            function<void(const kd_tree<D,point>*)> rec=[&](const kd_tree<D,point>* tree){
                auto d=dist(tree->p,q);
                if(d<mind){
                    mind=d;
                    res=tree;
                }
                if(q[tree->axis]<tree->p[tree->axis]){
                    if(tree->left!=NULL) rec(tree->left);
                    if(tree->right!=NULL and tree->p[tree->axis]-q[tree->axis]<=mind) rec(tree->right);
                }else{
                    if(tree->right!=NULL) rec(tree->right);
                    if(tree->left!=NULL and q[tree->axis]-tree->p[tree->axis]<=mind) rec(tree->left);
                }
            };
            rec(this);
            return res;
        }
        vector<point> range_search(const point& lb,const point& ub)const{
            vector<point> res;
            function<void(const kd_tree<D,point>*)> rec=[&](const kd_tree<D,point>* tree){
                bool in_range=true;
                for(int i=0; i<D; ++i) if(tree->p[i]<lb[i] or ub[i]<tree->p[i]){
                    in_range=false;
                    break;
                }
                if(in_range) res.push_back(tree->p);
                if(tree->left!=NULL and lb[tree->axis]<=tree->p[tree->axis]) rec(tree->left);
                if(tree->right!=NULL and ub[tree->axis]>=tree->p[tree->axis]) rec(tree->right);
            };
            rec(this);
            return res;
        }
    };
     
    const int loop=600000;
    const long double pi=acosl(-1),r=1e12;
    void solve(){
     
        int N;
        cin >> N;
     
        using point=vector<long double>;
        vector<pair<point,int>> ps(N);
        rep(i,0,N){
            ps[i].first.resize(2);
            ps[i].second=i;
            cin >> ps[i].first[0] >> ps[i].first[1];
        }
     
        kd_tree<2,point> kt(ps);
        vector<long double> cnt(N);
        print(r);
        rep(i,0,loop){
            auto p=polar(r,2*pi*i/loop);
            point q={p.real(),p.imag()};
            print(x);
            print(y);
            cnt[kt.nearest_neighbor(q)->val]+=1;
        }
     
        rep(i,0,N) cout << cnt[i]/loop << endl;
    }
     
    int main(){
        std::cin.tie(0);
        std::ios::sync_with_stdio(false);
        cout.setf(ios::fixed);
        cout.precision(16);
        solve();
        return 0;
    }


Measured memory_bytes: 384