import java.util.* ; public class fapple_tgr { static final double pi = 3.14159265358979323846; static final class seg implements Comparable { seg(seg s) { a = s.a ; b = s.b ; q = s.q ; } seg(double a_, double b_, int q_) { a = a_ ; b = b_ ; q = q_ ; } double a, b ; int q ; public int compareTo(Object o) { seg s2 = (seg)o ; if (a < s2.a) return -1 ; if (a > s2.a) return 1 ; if (b < s2.b) return -1 ; if (b > s2.b) return 1 ; return 0 ; } } ; static final class pt { pt(double x_, double y_) { x = x_ ; y = y_ ; } double x, y ; } ; static final class arc { arc(arc c) { a = c.a ; b = c.b ; ll = c.ll ; ur = c.ur ; } arc(circ c, seg seg) { a = new pt(c.x+c.r*Math.cos(seg.a), c.y+c.r*Math.sin(seg.a)) ; b = new pt(c.x+c.r*Math.cos(seg.b), c.y+c.r*Math.sin(seg.b)) ; ll = new pt(Math.min(a.x, b.x), Math.min(a.y, b.y)) ; ur = new pt(Math.max(a.x, b.x), Math.max(a.y, b.y)) ; } pt a, b ; pt ll, ur ; } ; static final class circ { circ(double x_, double y_, double r_) { x = x_ ; y = y_ ; r = r_ ; } double r, x, y ; ArrayList segs = new ArrayList() ; ArrayList toremove = new ArrayList() ; ArrayList arcs = new ArrayList() ; } ; static circ circs[] ; static void segfilter(circ c, double a, double b) { c.toremove.add(new seg(a,b,-1)) ; } static void segfilter2(circ c, double a, double b) { int r = 0 ; int w = 0 ; double adda = -100 ; double addb = -100 ; int addq = -1 ; while (r < c.segs.size()) { double aa = c.segs.get(r).a ; double bb = c.segs.get(r).b ; if (a <= aa && b >= bb) { r++ ; } else { if (r != w) c.segs.set(w, c.segs.get(r)) ; if (b <= aa || a >= bb) { // keep whole segment } else if (a <= aa) { // cut front if (r != w) c.segs.set(w, c.segs.get(r)) ; c.segs.get(w).a = b ; } else { // cut back, or split c.segs.get(w).b = a ; if (b < bb) { if (r != w) { w++ ; c.segs.set(w, new seg(b, bb, c.segs.get(r).q)) ; } else { adda = b ; addb = bb ; addq = c.segs.get(r).q ; } } } r++ ; w++ ; } } while (c.segs.size() > w) c.segs.remove(c.segs.size()-1) ; if (adda != -100) c.segs.add(new seg(adda, addb, addq)) ; } static void segfilterflush(circ c) { Collections.sort(c.toremove) ; if (c.toremove.size() != 0) { seg cs = c.toremove.get(0) ; double a = cs.a ; double b = cs.b ; for (int i=1; i= c.toremove.get(i).a) { b = Math.max(c.toremove.get(i).b, b) ; } else { segfilter2(c, a, b) ; a = c.toremove.get(i).a ; b = c.toremove.get(i).b ; } } segfilter2(c, a, b) ; } } static void addpts(circ c, double x1, double y1, double x2, double y2) { double a = Math.atan2(y1-c.y, x1-c.x) ; double b = Math.atan2(y2-c.y, x2-c.x) ; if (a > b) { segfilter(c, a, pi) ; segfilter(c, -pi, b) ; } else { segfilter(c, a, b) ; } } static double bound(double v, double lo, double hi) { return Math.min(hi, Math.max(lo, v)) ; } static double getang(double dx, double dy, seg seg) { switch(seg.q) { case 1: dx = - dx ; dy = - dy ; break ; case 2: dy = - dy ; break ; case 3: break ; case 4: dx = - dx ; break ; } return Math.atan2(dy, dx) ; } public static void main(String[] args) { Scanner sc = new Scanner(System.in) ; int n = sc.nextInt() ; int q = sc.nextInt() ; circs = new circ[n] ; for (int i=0; i c2.r) c2.segs.clear() ; else c1.segs.clear() ; } else if (d2 < c1.r + c2.r) { double xx = (d2 * d2 - c2.r * c2.r + c1.r * c1.r) / (2 * d2) ; double yy = Math.sqrt(c1.r * c1.r - xx * xx) ; double xc = xx * (c2.x - c1.x) ; double yc = xx * (c2.y - c1.y) ; double xs = yy * (c2.y - c1.y) ; double ys = -yy * (c2.x - c1.x) ; double x1 = (xc + xs) / d2 + c1.x ; double y1 = (yc + ys) / d2 + c1.y ; double x2 = (xc - xs) / d2 + c1.x ; double y2 = (yc - ys) / d2 + c1.y ; addpts(c1, x1, y1, x2, y2) ; addpts(c2, x2, y2, x1, y1) ; } } segfilterflush(c1) ; } for (int i=0; i= x2 || arc.ur.x <= x1) // to left or right continue ; if (arc.ur.y <= y1) // below continue ; if (arc.ll.y >= y2) { // above s += h * (bound(arc.b.x, x1, x2) - bound(arc.a.x, x1, x2)) ; continue ; } arc arc2 = arc ; seg seg2 = new seg(seg) ; if ((arc.ll.x < x1 || arc.ur.x > x2 || arc.ll.y < y1 || arc.ur.y > y2)) { if (arc2.ll.x < x1) { // trim left side double dx = Math.abs(c.x - x1) ; double na = getang(dx, Math.sqrt(c.r*c.r-dx*dx), seg2) ; if (seg2.q > 2) seg2.b = na ; else seg2.a = na ; arc2 = new arc(c, seg2) ; } if (arc2.ur.x > x2) { // trim right side double dx = Math.abs(c.x - x2) ; double na = getang(dx, Math.sqrt(c.r*c.r-dx*dx), seg2) ; if (seg2.q <= 2) seg2.b = na ; else seg2.a = na ; arc2 = new arc(c, seg2) ; } if (arc2.ll.y < y1) { // trim bot double dy = Math.abs(c.y - y1) ; double na = getang(Math.sqrt(c.r*c.r-dy*dy), dy, seg2) ; if (seg2.q > 1 && seg2.q < 4) seg2.a = na ; else seg2.b = na ; arc2 = new arc(c, seg2) ; } if (arc2.ur.y > y2) { // trim top double dy = Math.abs(c.y - y2) ; double na = getang(Math.sqrt(c.r*c.r-dy*dy), dy, seg2) ; if (seg2.q <= 1 || seg2.q >= 4) seg2.a = na ; else seg2.b = na ; if (seg2.b > seg2.a) { arc arc3 = new arc(c, seg2) ; s -= h * (arc3.b.x - arc3.a.x - arc2.b.x + arc2.a.x) ; arc2 = arc3 ; } else { s += h * (bound(arc2.b.x, x1, x2) - bound(arc2.a.x, x1, x2)) ; } } } double theta = seg2.b - seg2.a ; if (theta > 0) { s += 0.5 * (arc2.a.y + arc2.b.y - 2 * y1) * (arc2.b.x - arc2.a.x) ; if ((seg2.q > 2) == (arc2.b.x > arc2.a.x)) { // above; add s += 0.5 * c.r * c.r * (theta - Math.sin(theta)) ; } else { // below; subtract s -= 0.5 * c.r * c.r * (theta - Math.sin(theta)) ; } } } } System.out.println(-100*s/(w*h)) ; } } }