题意
给定 n 个点 $\left\{ p_i = (a_i, b_i) \right\}$ , 求 $\max_{i, j} |p_i \times p_j|$ .
n <= 100000 .
分析
凸包 + 三分 .
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #include <algorithm> 6 using namespace std; 7 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 8 #define LL long long 9 inline LL rd(void) { 10 LL f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -1; 11 LL x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-‘0‘; return x*f; 12 } 13 inline LL Abs(LL x) { return x < 0 ? -x : x; } 14 15 const int N = 200005; 16 17 int n, Len; 18 struct point { 19 LL x, y; 20 friend inline point operator - (point A, point B) { return (point){ A.x - B.x, A.y - B.y }; } 21 friend inline LL det(point A, point B) { return A.x * B.y - A.y * B.x; } 22 }Origin, p[N], s[N]; 23 inline bool operator < (point A, point B) { return det(A - Origin, B - Origin) > 0; } 24 25 void Build(void) { 26 int ID = 1; 27 F(i, 2, n) 28 if (p[ID].y > p[i].y || (p[ID].y == p[i].y && p[ID].x > p[i].x)) 29 ID = i; 30 swap(p[1], p[ID]); 31 sort(p+2, p+n+1); 32 F(i, 1, n) { 33 while (Len >= 2 && det(p[i] - s[Len-1], s[Len] - s[Len-1]) >= 0) 34 s[Len--] = (point){ 0, 0 }; 35 s[++Len] = p[i]; 36 } 37 } 38 39 inline LL Calc(point A, point B) { return Abs(det(A, B)); } 40 inline LL Search(point A, int l, int r) { 41 while (r-l > 3) { 42 int _l = (l + l + r) / 3; LL ansL = Calc(A, s[_l]); 43 int _r = (l + r + r) / 3; LL ansR = Calc(A, s[_r]); 44 ansL < ansR ? l = _l : r = _r; 45 } 46 LL res = 0; 47 F(i, l, r) 48 res = max(res, Calc(A, s[i])); 49 return res; 50 } 51 52 int main(void) { 53 #ifndef ONLINE_JUDGE 54 freopen("convex.in", "r", stdin); 55 #endif 56 57 n = rd(); 58 F(i, 1, n) { 59 LL G = rd(), R = rd(); 60 p[i] = (point){ G, R }; 61 } 62 63 Build(); 64 F(i, Len+1, Len+Len) 65 s[i] = s[i - Len]; 66 67 LL res = 0; 68 F(i, 1, Len) 69 res = max(res, Search(s[i], i+1, i+Len)); 70 printf("%lld\n", res); 71 72 return 0; 73 }
时间: 2024-10-07 05:16:19