#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <math.h>
#include <stdbool.h>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;

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

typedef Point Vector;

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

//ポイントpがベクトルp1-p0からみて反時計回りにいるかどうか
//CCW: 1, CW: -1, ON:0
int isCCW(Point p, Point p0, Point p1){
    Vector v01 = p1 - p0;
    Vector v02 = p - p0;

    double Cross = cross(v01, v02);
    
    int out = 2;
    if (Cross>0){out = 1;}
    else if(Cross<0){out = -1;}
    else{out = 0;}

    return out;
}


Point getCrossPoint(Point p0, Point p1, Point e0, Point e2);
double getPolygonArea(vector<Point> vdPolygon);
double getCutPolygonArea(vector<Point> vdPolygon, Point p0, Point p1);

int main(){
    #if 0
    std::ifstream in("input.txt");
    std::cin.rdbuf(in.rdbuf());
    #endif

    int n;
    cin >> n;
    vector<Point> vdPolygon(n);

    for (int i=0; i<n; i++){
        cin >> vdPolygon[i].x >> vdPolygon[i].y;
    }

    int q;
    cin >> q;

    for (int i=0; i<q; i++){
        Point p0, p1;
        cin >> p0.x >> p0.y >> p1.x >> p1.y;
        //cout << getPolygonArea(vdPolygon) << endl;
        cout << setprecision(14) << getCutPolygonArea(vdPolygon, p0, p1) << endl;
    }
    return 0;
}

Point getCrossPoint(Point p1, Point p2, Point p3, Point p4){
    double ksi, eta, delta;
	double ramda, mu;
    Point crossPoint;

	ksi = ( p4.y-p3.y )*( p4.x-p1.x ) - ( p4.x-p3.x )*( p4.y-p1.y );
	eta = ( p2.x-p1.x )*( p4.y-p1.y ) -( p2.y-p1.y )*( p4.x-p1.x );
	delta = ( p2.x-p1.x )*( p4.y-p3.y ) - ( p2.y-p1.y )*( p4.x-p3.x );

	ramda = ksi / delta;
	mu    = eta / delta;

    crossPoint.x = p1.x + ramda*( p2.x-p1.x );
	crossPoint.y = p1.y + ramda*( p2.y-p1.y );

    return crossPoint;
}

double getPolygonArea(vector<Point> vdPolygon){
    int n = vdPolygon.size();
    double area = 0;
    Point p0 = vdPolygon[0];

    for (int i=1; i<n-1; i++){
        Point p1 = vdPolygon[i];
        Point p2 = vdPolygon[i+1];
        area += fabs( cross(p1-p0, p2-p0) ) * 0.5;
    }
    return area;
}

double getCutPolygonArea(vector<Point> vdPolygon, Point p0, Point p1){
    int n = vdPolygon.size();
    vector<Point> cutPolygon;
    vector<vector<int> > crossEdge; //(index, state_i, state_i+1) state=(-1:CW,0:ON,1:CCW)

    //crossEdgeに詰めてく。直線上に辺が乗る場合は直ちに処理を終了。
    for(int i=0; i<n; i++){
        Point e0 = vdPolygon[i];
        Point e1 = vdPolygon[(i+1)%n];

        int state0 = isCCW(e0, p0, p1);
        int state1 = isCCW(e1, p0, p1);

        if (state0 != state1){ //辺が直線を横切るor片方の端点が直線上に乗る場合
            int tmp[] = {i, state0, state1};
            vector<int> v(tmp, tmp+3);
            crossEdge.push_back(v);
        } else if (state0 == 0 && state1 == 0){ //直線上に辺が乗る場合:All or Nothing
            bool isAll = false;
            for (int j=0; j<n; j++){
                if (isCCW(vdPolygon[j], p0, p1) != 0){
                    isAll = (isCCW(vdPolygon[j], p0, p1) == 1);
                }
            }
            if (isAll){
                return getPolygonArea(vdPolygon);
            }else { 
                return 0.0;
            }
        }
    }

    //直線が多角形を横切らない場合
    if (crossEdge.size() == 0){
        if ( isCCW(vdPolygon[0], p0, p1) == 1 ){
            return getPolygonArea(vdPolygon);
        } else{
            return 0.0;
        }
    }

    else if (crossEdge.size() == 2){
        int index0 = crossEdge[0][0];
        int index1 = crossEdge[1][0];
        //直線が多角形の点を通るだけの場合
        if ( ( (index0 + 1)%n == index1) && crossEdge[0][2]==0 && crossEdge[1][1]==0 ){
            if ( isCCW(vdPolygon[index0], p0, p1) == 1 ){
                return getPolygonArea(vdPolygon);
            }else {
                return 0.0;
            }
        }
        if ( ( (index1 + 1)%n == index0) && crossEdge[1][2]==0 && crossEdge[0][1]==0 ){
            if ( isCCW(vdPolygon[index1], p0, p1) == 1 ){
                return getPolygonArea(vdPolygon);
            }else {
                return 0.0;
            }
        }
        //直線が多角形の２辺上を通る場合
        Point crossPoint0 = getCrossPoint(p0, p1, vdPolygon[index0], vdPolygon[ (index0+1)%n ]);
        Point crossPoint1 = getCrossPoint(p0, p1, vdPolygon[index1], vdPolygon[ (index1+1)%n ]);
        
        if (crossEdge[0][1] == 1){
            for (int i=0; i<=index0; i++){
                cutPolygon.push_back(vdPolygon[i]);
            }
            cutPolygon.push_back(crossPoint0);
            cutPolygon.push_back(crossPoint1);
            for (int i=index1+1; i<n; i++){
                cutPolygon.push_back(vdPolygon[i]);
            }
        }else {
            cutPolygon.push_back(crossPoint0);
            for (int i=index0+1; i<=index1; i++){
                cutPolygon.push_back(vdPolygon[i]);
            }
            cutPolygon.push_back(crossPoint1);
        }
    }

    else if (crossEdge.size() == 3){
        int index0 = crossEdge[0][0];
        int index1 = crossEdge[1][0];
        int index2 = crossEdge[2][0];

        if (isCCW(vdPolygon[index0], p0, p1) == 0){
            Point crossPoint1 = getCrossPoint(p0, p1, vdPolygon[index1], vdPolygon[index1+1]);
            if (isCCW(vdPolygon[index0+1], p0, p1) == 1){
                for (int i=index0; i<=index1; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
                cutPolygon.push_back(crossPoint1);
            }else {
                for (int i = 0; i<=index0; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
                cutPolygon.push_back(crossPoint1);
                for (int i=index1+1; i<n; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
            }
        }

        if (isCCW(vdPolygon[index1], p0, p1) == 0){
            Point crossPoint2 = getCrossPoint(p0, p1, vdPolygon[index2], vdPolygon[ (index2+1)%n ]);
            if (isCCW(vdPolygon[index1+1], p0, p1) == 1){
                for (int i=index1; i<=index2; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
                cutPolygon.push_back(crossPoint2);
            }else {
                for (int i=0; i<=index1; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
                cutPolygon.push_back(crossPoint2);
                for (int i=index2+1; i<n; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
            }
        }

        if (isCCW(vdPolygon[index2], p0, p1) == 0){
            Point crossPoint0 = getCrossPoint(p0, p1, vdPolygon[index0], vdPolygon[index0+1]);
            if (isCCW(vdPolygon[(index2+1)%n], p0, p1) == 1){
                for (int i=0; i<=index0; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
                cutPolygon.push_back(crossPoint0);
                for (int i=index2; i<n; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
            }else {
                cutPolygon.push_back(crossPoint0);
                for (int i=index0+1; i<=index2; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
            }
        }

    }

    else if (crossEdge.size() == 4){
        int index0 = crossEdge[0][0];
        int index1 = crossEdge[1][0];
        int index2 = crossEdge[2][0];
        int index3 = crossEdge[3][0];
        
        //(0,1),(2,3)パターン
        if (isCCW(vdPolygon[index0+1], p0, p1) == 0){
            if (isCCW(vdPolygon[index0], p0, p1) == 1){
                for (int i=0; i<=index1; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
                for (int i=index3; i<n; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
            }else {
                for (int i=index1; i<=index3; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
            }
        }

        //(0,3),(1,2)パターン
        if (isCCW(vdPolygon[index0], p0, p1) == 0){
            if (isCCW(vdPolygon[index0+1], p0, p1) == 1){
                for (int i=index0; i<=index2; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
            }else {
                for (int i=0; i<=index0; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
                for (int i=index2; i<n; i++){
                    cutPolygon.push_back(vdPolygon[i]);
                }
            }
        }
        
    }

    else {
        return -1.0;
    }

    return getPolygonArea(cutPolygon);
}



Measured memory_bytes: 3288