1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #include<bits/stdc++.h> using namespace std; typedef long long LL;
const int MAXN = 100000 + 10; const int EPS = 100;
struct Point{ double x, y; } P[MAXN], L, R, T; Point operator - (Point& A,Point& B) { return (Point){A.x - B.x, A.y - B.y}; }
LL Gcd(LL a,LL b) { return b == 0? a: Gcd(b, a % b); } double Cross(Point A,Point B) { return A.x * B.y - A.y * B.x; }
double p2[MAXN], Ans, Base, Area, S; int N;LL pcnt, cur, bdcnt;
#define Pick(S, b) (S + 1.0 - (b) * 0.5) #define NXT(x) ((x + 1) % N) #define gcd(x, y) Gcd(abs(x), abs(y)) #define prob(k) (N > EPS ? 1.0 / p2[k+1] : ((p2[N - (k) - 1] - 1.0) / Base))
int main(){ if(fopen("input.txt","r")){ freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); }
scanf("%d", &N); p2[0] = 1.0; for(int i = 0;i < N; ++i){ scanf("%lf%lf", &P[i].x, &P[i].y); p2[i + 1] = p2[i] * 2.0; }
Base = p2[N] - 1 - N - 0.5 * N * (N - 1);
R = P[N - 1] - P[0]; bdcnt += gcd(R.x, R.y); R = P[1] - P[0]; bdcnt += gcd(R.x, R.y);
for(int i = 2;i < N; ++i){ L = P[i] - P[0]; T = P[i] - P[i - 1]; Area += Cross(R, L) * 0.5; bdcnt += gcd(T.x, T.y); R = L; }
for(int i = 0;i < N; ++i){ R = P[NXT(i)] - P[i]; pcnt = gcd(R.x, R.y); S = 0; for(int j = NXT(NXT(i)), k = 2;k <= 35 && NXT(j) != i; ++k,j = NXT(j)){ L = P[j] - P[i]; T = L - R; pcnt += (cur = gcd(L.x, L.y)) + gcd(T.x, T.y); S += Cross(R, L) * 0.5; Ans += (Pick(S, pcnt) + (NXT(j) == i ? 0 : cur - 1)) * prob(k); R = L; pcnt -= cur; } }
printf("%.10lf", Pick(Area, bdcnt) - Ans); return 0; }
|