/** * Calculates the greatest common divisor of two integers, uses the Euclidean method. * * @param m One integer * @param n One integer * @return An integer with the greatest common divisor of i and n Triple containing the */ long gcd(long m, long n){ struct Triple z; if (m==n) return m; if (m>n) z = Euclid(n, m); else z = Euclid(m, n); return z.d; }
/** * Euclid's algorithm * Recursive method to calculate the greatest common divisor of two integers * Also used to calculate the modular multiplicative inverse * * @param i The smaller of the integers * @param n The largest of the integers (i<=n) * @return A Triple containing the GCD(i,n), the MMI(i,n) and the MMI(n,i) */ struct Triple Euclid(long m, long n) { struct Triple t, v, w; long q, r; long d1, k1, m1; if (m == 0) { t.d = n; t.k = 1; t.m = 0; return t; } q = n % m; r = n/m; v = Euclid(q,m); d1 = v.d; k1 = v.k; m1 = v.m; w.d = d1; w.k = m1; w.m = k1 - m1*r; return w; }
/** * Calculates the modular multiplicative inverse of an integer i modulo n * GCD(i,n) must be 1 * @param i The smaller of the integers * @param n The largest of the integers (i<=n) * @return An integer with the inverse of i modulo n */ long inverse(long i, long n){ struct Triple z; z = Euclid(i, n); if(z.m < 0) z.m += n; return z.m; }
void solve() { bool bInside; double dx, dy; int i; for (dx = EPS; dx < 1; dx += EPS2) for (dy = EPS; dy < 1; dy += EPS2) { bInside = false; for (i = 0; i < N; i++) if (Euclid(dx, dy, C[i].x, C[i].y) <= C[i].rad) { bInside = true; break; } if (!bInside) dArea += EPS; } printf("%.7lf\n", 100 - dArea * 100); }
/** * Reduce the modulo guard expressed by "contraints" using equalities * found in outer nesting levels (stored in "equal"). * The modulo guard may be an equality or a pair of inequalities. * In case of a pair of inequalities, "constraints" only contains the * upper bound and *bound contains the bound on the * corresponding modulo expression. The bound is left untouched by * this function. */ CloogConstraintSet *cloog_constraint_set_reduce(CloogConstraintSet *constraints, int level, CloogEqualities *equal, int nb_par, cloog_int_t *bound) { int i, j, k, len, len2, nb_iter; struct cloog_vec *line_vector2; cloog_int_t *line, *line2, val, x, y, g; len = constraints->M.NbColumns; len2 = cloog_equal_total_dimension(equal) + 2; nb_iter = len - 2 - nb_par; cloog_int_init(val); cloog_int_init(x); cloog_int_init(y); cloog_int_init(g); line_vector2 = cloog_vec_alloc(len2); line2 = line_vector2->p; line = constraints->M.p[0]; if (cloog_int_is_pos(line[level])) cloog_seq_neg(line+1, line+1, len-1); cloog_int_neg(line[level], line[level]); assert(cloog_int_is_pos(line[level])); for (i = nb_iter; i >= 1; --i) { if (i == level) continue; cloog_int_fdiv_r(line[i], line[i], line[level]); if (cloog_int_is_zero(line[i])) continue; /* Look for an earlier variable that is also a multiple of line[level] * and check whether we can use the corresponding affine expression * to "reduce" the modulo guard, where reduction means that we eliminate * a variable, possibly at the expense of introducing other variables * with smaller index. */ for (j = level-1; j >= 0; --j) { CloogConstraint *equal_constraint; if (cloog_equal_type(equal, j+1) != EQTYPE_EXAFFINE) continue; equal_constraint = cloog_equal_constraint(equal, j); cloog_constraint_coefficient_get(equal_constraint, j, &val); if (!cloog_int_is_divisible_by(val, line[level])) { cloog_constraint_release(equal_constraint); continue; } cloog_constraint_coefficient_get(equal_constraint, i-1, &val); if (cloog_int_is_divisible_by(val, line[level])) { cloog_constraint_release(equal_constraint); continue; } for (k = j; k > i; --k) { cloog_constraint_coefficient_get(equal_constraint, k-1, &val); if (cloog_int_is_zero(val)) continue; if (!cloog_int_is_divisible_by(val, line[level])) break; } if (k > i) { cloog_constraint_release(equal_constraint); continue; } cloog_constraint_coefficient_get(equal_constraint, i-1, &val); Euclid(val, line[level], &x, &y, &g); if (!cloog_int_is_divisible_by(val, line[i])) { cloog_constraint_release(equal_constraint); continue; } cloog_int_divexact(val, line[i], g); cloog_int_neg(val, val); cloog_int_mul(val, val, x); cloog_int_set_si(y, 1); /* Add (equal->p[j][i])^{-1} * line[i] times the equality */ cloog_constraint_copy_coefficients(equal_constraint, line2+1); cloog_seq_combine(line+1, y, line+1, val, line2+1, i); cloog_seq_combine(line+len-nb_par-1, y, line+len-nb_par-1, val, line2+len2-nb_par-1, nb_par+1); cloog_constraint_release(equal_constraint); break; } } cloog_vec_free(line_vector2); cloog_int_clear(val); cloog_int_clear(x); cloog_int_clear(y); cloog_int_clear(g); /* Make sure the line is not inverted again in the calling function. */ cloog_int_neg(line[level], line[level]); return constraints; }