luogu P4423 [BJWC2011]最小三角形

传送门

数据范围n<=200000

类似平面最近点对的题

我们考虑平面最近点对的实现过程

二分的时候其实开了一个tmp数组存可能与枚举的点成为答案的点

而且一个非常优秀的性质就是元素个数是常数

所以这里同样沿用 tmp存到中线距离<=答案/2的点

因为大于答案/2的话一定总周长是更大的

剩下的和板子一样了

(然后我这里没用归并排序嘤嘤嘤)

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<queue>
 6 #include<iostream>
 7 #define B puts("GGGGGGG");
 8 #define ms(a,b) memset(a,b,sizeof a)
 9 #define rep(i,a,n) for(int i = a;i <= n;i++)
10 #define per(i,n,a) for(int i = n;i >= a;i--)
11 #define inf 2147483647
12 using namespace std;
13 typedef long long ll;
14 ll read() {
15     ll as = 0,fu = 1;
16     char c = getchar();
17     while(c < '0' || c > '9') {
18         if(c == '-') fu = -1;
19         c = getchar();
20     }
21     while(c >= '0' && c <= '9') {
22         as = as * 10 + c - '0';
23         c = getchar();
24     }
25     return as * fu;
26 }
27 const int N = 200003;
28 //head
29 typedef double D;
30 int n;
31 struct point {
32     D x,y;
33     point operator - (const point &a) const {
34         return (point){x - a.x,y - a.y};
35     }
36     D len() {return sqrt(x*x+y*y);}
37 }p[N];
38 bool cmpx(point x,point y) {
39     return x.x < y.x;
40 }
41 bool cmpy(point x,point y) {
42     return x.y < y.y;
43 }
44 
45 //[l,r)
46 D solve(int l,int r) {
47     if(r - l <= 1) return inf;
48     if(r - l == 2) {
49         // res[l][r] = (ans){p[l],p[l+1],p[r]};
50         return (p[l+1] - p[l]).len() + (p[r] - p[l+1]).len() + (p[r] - p[l]).len();
51     }
52     int m = l+r >> 1;
53     D midx = (p[m].x + p[m-1].x) / 2.0;
54     D d = min(solve(l,m),solve(m,r));
55     // D d1 = solve(l,m),d2 = solve(m,r),d;
56     // if(d1 < d2) res[l][r] = res[l][m],d = d1;
57     // else res[l][r] = res[m][r],d = d2;
58     D lim = d / 2.0;
59     static point tmp[N];
60     int top = 0;
61     rep(i,l,r - 1) if(fabs(p[i].x - midx) <= lim) tmp[++top] = p[i];
62     sort(tmp+1,tmp+1+top,cmpy);
63     int cur = 1;
64     rep(i,1,top) {
65         while(cur <= top && fabs(tmp[i].y - tmp[cur].y) <= lim) cur++;
66         rep(u,i+1,cur-1) rep(v,i+1,u-1) {
67             // if((tmp[i] - tmp[u]).len() + (tmp[i] - tmp[v]).len() + (tmp[u] - tmp[v]).len() < d) res[l][r] = (ans){p[v],p[u],p[i]};
68             d = min(d,(tmp[i] - tmp[u]).len() + (tmp[i] - tmp[v]).len() + (tmp[u] - tmp[v]).len());
69         }
70     }
71     return d;
72 }
73 
74 int main() {
75     // freopen("in.in","r",stdin);
76     n = read();
77     rep(i,1,n) scanf("%lf%lf",&p[i].x,&p[i].y);
78     sort(p+1,p+n+1,cmpx);
79     printf("%.6f\n",solve(1,n+1));
80     // printf("%lf %lf %lf %lf %lf %lf\n",res[1][n+1].a.x,res[1][n+1].a.y,res[1][n+1].b.x,res[1][n+1].b.y,res[1][n+1].c.x,res[1][n+1].c.y);
81     // rep(i,1,n) printf("%.2lf %.2lf\n", p[i].x,p[i].y);
82     return 0;
83 }

猜你喜欢

转载自www.cnblogs.com/yuyanjiaB/p/10043499.html