The two-point answer, the conversion to determine whether to divide into no more than M segment, and the minimum circle for each section to obtain the radius of the circle does not exceed mid.
For the current I, multiply a J so that the [i,i+ (1<<J)-1] interval does not meet the conditions, and then find the largest t in the [i+ (1<< (j-1)) -1,i+ (1<<J)-1] interval binary, so that [i,t] satisfies the condition , and then zoned for a paragraph.
Time complexity $o (N\LOG^2N) $.
#include <cstdio> #include <cstdlib> #include <algorithm> #include <cmath> #define N 100010using Namespace Std;int n,m,i,t=50,cnt,ans[n][2];d ouble l,r,mid,r,eps=1e-10;struct p{double x, y;} B[n],a[n],o;inline double dis (P x,p y) {return sqrt ((x.x-y.x) * (x.x-y.x) + (X.Y-Y.Y) * (X.Y-Y.Y));} Inline P Center (p x,p y,p z) {double a1=y.x-x.x,b1=y.y-x.y,c1= (A1*A1+B1*B1)/2,a2=z.x-x.x,b2=z.y-x.y,c2= (A2*A2+B2*B2)/ 2,D=A1*B2-A2*B1; Return (P) {x.x+ (C1*B2-C2*B1)/d,x.y+ (A1*C2-A2*C1)/d};} inline void cal (int l,int r) {int i,j,k,n=0; for (i=l;i<=r;i++) a[n++]=b[i]; for (i=0;i<n;i++) swap (A[rand ()%n],a[i]); for (o=a[0],r=0,i=1;i<n;i++) if (DIS (a[i],o) >r+eps) for (o=a[i],r=0,j=0;j<i;j++) if (DIS (a[j],o) >r+eps) For (o= (P) {(a[i].x+a[j].x)/2, (A[I].Y+A[J].Y)/2},r=dis (O,a[i]), k=0;k<j;k++) if (DIS (a[k],o) >r+eps) O=center (a [K],a[j],a[i]), R=dis (O,a[i]);} inline bool Check (double x) {int i,j,l,r,mid,t,now=0; for (i=1;i<=n;i=t+1) {for (j=1;i+ (1<<j) -1<=n;j++) {cal (i,i+ (1<<J)-1); if (r>x+eps) break; } t=i,l=i+ (1<< (j-1)) -1,r=i+ (1<<j)-1; if (r>n) r=n; while (l<=r) {cal (i,mid= (L+R) >>1); if (r<x+eps) l= (t=mid) +1;else r=mid-1; } if ((++now) >m) return 0; } return 1;} inline void fin (double x) {int i,j,l,r,mid,t; for (i=1;i<=n;i=t+1) {for (j=1;i+ (1<<j) -1<=n;j++) {cal (i,i+ (1<<J)-1); if (r>x+eps) break; } t=i,l=i+ (1<< (j-1)) -1,r=i+ (1<<j)-1; if (r>n) r=n; while (l<=r) {cal (i,mid= (L+R) >>1); if (r<x+eps) l= (t=mid) +1;else r=mid-1; } ans[++cnt][0]=i,ans[cnt][1]=t; }}int Main () {scanf ("%d%d", &n,&m); for (i=1;i<=n;i++) scanf ("%lf%lf", &b[i].x,&b[i].y); Cal (1,n); R=r; if (m>1) while (t--&&r-l>eps) if (check (mid= (l+r)/2) R=mid;else L=mid; printf ("%.8f\n", R); Fin (R); printf ("%d\n", CNT); for (i=1;i<=cnt;i++) Cal (Ans[i][0],ans[i][1]), printf ("%.8f%.8f\n", o.x,o.y); return 0;}
BZOJ2280: [Poi2011]plot