恩。。这题真是sxbk
我们先二分答案,然后判断答案是否满足要求
判断方法是二分当前段的长度一直做到底,当然我们可以用倍增这样快一点,直接随机增量就可以了
然后就是卡常。。。。。
然后就是卡精度QAQQQQQQQ没了
1 /************************************************************** 2 Problem: 2280 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:90955 ms 7 Memory:7068 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cmath> 12 #include <algorithm> 13 14 using namespace std; 15 typedef double lf; 16 typedef long double LF; 17 const int N = 1e5 + 5; 18 const LF eps = 1e-7; 19 const LF EPS = 1e-13; 20 const LF inf = 1e8; 21 22 inline int read(); 23 inline void print(const lf&); 24 25 template <class T> inline T sqr(const T &x) { 26 return x * x; 27 } 28 29 struct point { 30 lf x, y; 31 point() {} 32 point(lf _x, lf _y) : x(_x), y(_y) {} 33 34 friend inline point operator + (const point &p, const point &q) { 35 return point(p.x + q.x, p.y + q.y); 36 } 37 friend inline point operator - (const point &p, const point &q) { 38 return point(p.x - q.x, p.y - q.y); 39 } 40 friend inline LF operator * (const point &p, const point &q) { 41 return p.x * q.y - p.y * q.x; 42 } 43 friend inline point operator / (const point &p, const LF &d) { 44 return point(p.x / d, p.y / d); 45 } 46 47 inline void read_in() { 48 x = read(), y = read(); 49 } 50 inline void print_out() { 51 print(x), putchar(' '), print(y), putchar(' '); 52 } 53 friend inline LF dis2(const point &p) { 54 return sqr((LF) p.x) + sqr((LF) p.y); 55 } 56 friend inline lf dis(const point &p) { 57 return sqrt(dis2(p)); 58 } 59 friend inline point work(const point &a, const point &b, const point &c) { 60 point p = b - a, q = c - a, res; 61 LF d = p * q * 2; 62 if (fabs(d) < EPS) { 63 lf ab = dis2(b - a), bc = dis2(c - b), ac = dis2(c - a); 64 if (ab - bc >= EPS && ab - ac >= EPS) return (a + b) / 2; 65 if (bc - ab >= EPS && bc - ac >= EPS) return (b + c) / 2; 66 return (a + c) / 2; 67 } 68 return point(dis2(p) * q.y - dis2(q) * p.y, dis2(q) * p.x - dis2(p) * q.x) / d + a; 69 } 70 } p[N], q[N], c[N], ans[N]; 71 72 int n, m, cnt; 73 LF rad, now_ans; 74 75 inline void min_cover(const int &L, const int &st, const int &R) { 76 static int i, j, k; 77 for (i = st; i <= R; ++i) if (dis2(q[i] - c[cnt]) > rad) { 78 c[cnt] = q[i], rad = 0.0; 79 for (j = L; j < i; ++j) if (dis2(q[j] - c[cnt]) > rad) { 80 c[cnt] = (q[i] + q[j]) / 2.0, rad = dis2(q[i] - c[cnt]); 81 for (k = L; k < j; ++k) if (dis2(q[k] - c[cnt]) > rad) 82 c[cnt] = work(q[i], q[j], q[k]), rad = dis2(q[i] - c[cnt]); 83 } 84 } 85 } 86 87 inline bool check(const int &l, const int &st, const int &r) { 88 static int i; 89 for (i = st; i <= r; ++i) q[i] = p[i]; 90 random_shuffle(q + st, q + r + 1); 91 if (st == l) c[cnt] = q[l], rad = 0.0; 92 min_cover(l, st, r); 93 return rad < now_ans + eps; 94 } 95 96 inline bool check_ans() { 97 static int l, len, del; 98 cnt = l = 0, del = 1; 99 while (l + del <= n) { 100 ++cnt; 101 if (cnt > m) return 0; 102 l += del, del = 0; 103 for (len = 1; l + len - 1 <= n && check(l, l + (len >> 1), l + len - 1); len <<= 1); 104 del += (len >>= 1); 105 for (; len; len >>= 1) 106 if (l + del + len - 1 <= n && check(l, l, l + del + len - 1)) del += len; 107 } 108 return 1; 109 } 110 111 inline void get_ans() { 112 static int l, len, del; 113 cnt = l = 0, del = 1; 114 while (l + del <= n) { 115 ++cnt; 116 l += del, del = 0; 117 for (len = 1; l + len - 1 <= n && check(l, l + (len >> 1), l + len - 1); len <<= 1); 118 del += (len >>= 1); 119 for (; len; len >>= 1) 120 if (l + del + len - 1 <= n && check(l, l, l + del + len - 1)) del += len; 121 check(l, l, l + del - 1), ans[cnt] = c[cnt]; 122 } 123 } 124 125 int main() { 126 int i; 127 LF ansl, ansr, mid; 128 n = read(), m = read(); 129 for (i = 1; i <= n; ++i) p[i].read_in(); 130 ansl = 0, ansr = inf; 131 while (ansr - ansl > eps) { 132 mid = (ansl + ansr) / 2.0; 133 now_ans = sqr(mid); 134 if (check_ans()) ansr = mid; 135 else ansl = mid; 136 } 137 now_ans = sqr(ansr); 138 get_ans(); 139 print(ansr); 140 printf(" %d ", cnt); 141 for (i = 1; i <= cnt; ++i) ans[i].print_out(); 142 return 0; 143 } 144 145 inline int read() { 146 static int x, sgn; 147 static char ch; 148 x = 0, sgn = 1, ch = getchar(); 149 while (ch < '0' || '9' < ch) { 150 if (ch == '-') sgn = -1; 151 ch = getchar(); 152 } 153 while ('0' <= ch && ch <= '9') { 154 x = x * 10 + ch - '0'; 155 ch = getchar(); 156 } 157 return sgn * x; 158 } 159 160 inline void print(const lf &x) { 161 static int a, tot, pr[20]; 162 static lf t; 163 if (x < 0) putchar('-'), t = -x; 164 else t = x; 165 a = (int) t, t -= a, tot = 0; 166 while (a) 167 pr[++tot] = a % 10, a /= 10; 168 if (!tot) putchar('0'); 169 while (tot) putchar(pr[tot--] + '0'); 170 putchar('.'); 171 for (tot = 1; tot <= 8; ++tot) 172 t *= 10, putchar((int) t % 10 + '0'); 173 }
(p.s. 数据在这里,求不要像我一样虐萌萌哒main和bz评测姬)