BZOJ 2564
跟这道题挺像的,就不再多讲了。
#include <bits/stdc++.h> using namespace std; const int N = 2e5 + 10; typedef long long ll; struct Point { ll x, y; Point(){x=y=0;} Point(ll _x, ll _y):x(_x),y(_y){} Point operator-(const Point& _p) const{return Point(x-_p.x, y-_p.y);} Point operator+(const Point& _p) const{return Point(x+_p.x, y+_p.y);} ll operator*(const Point& _p) const{return x * _p.x + y * _p.y;} ll operator^(const Point& _p) const{return x*_p.y - y*_p.x;} void input(){scanf("%lld%lld", &x, &y);} /*sort*/ bool operator==(const Point& _p) const{return x==_p.x&&y==_p.y;} bool operator<(const Point& _p) const{return x==_p.x ? y<_p.y : x<_p.x;} } A[N], B[N], C[N]; ll cro(Point a, Point b, Point c) {return (b-a) ^ (c-a);} ll dot(Point a, Point b, Point c) {return (b-a) * (c-a);} int ConvexHull(Point *p, int n, Point* ch, int flag=1) { sort(p, p+n); //先比较x坐标,再比较y坐标 if (flag) n = unique(p, p+n)-p; int m = 0; for (int i = 0; i < n; ++ i) { while (m > 1 && cro(ch[m-2], ch[m-1], p[i]) < flag) -- m; ch[m++] = p[i]; } int temp = m; for (int i = n - 2; i >= 0; -- i) { while (m > temp && cro(ch[m-2], ch[m-1], p[i]) < flag) -- m; ch[m++] = p[i]; } return m -= (n > 1); } //点在线段上(包含端点),在为 1 ,不在为 0 bool isPointOnSegment(Point P,Point A,Point B) { return cro(P, A, B) == 0 && dot(P, A, B) <= 0; // 不包含端点时为 <0 } //判断点在凸包内模板 O(logn) //凸包为逆时针 //在边界,返回0,在内部,返回1,在外部,返回-1 int check(Point A, Point*p, int n ) { if (isPointOnSegment(A, p[0], p[1])) return 0; // 包含端点 if (isPointOnSegment(A, p[0], p[n-1])) return 0; int l = 1, r = n - 2, mid; while (l <= r) { mid = l + r >> 1; ll a1 = cro(p[0], p[mid], A); ll a2 = cro(p[0], p[mid+1], A); if (a1 >= 0 && a2 <= 0) { ll tmp = cro(p[mid], p[mid+1], A); if (tmp > 0)return 1; if (tmp == 0) return 0; return -1; } else if (a1 < 0) r = mid - 1; else l = mid + 1; } return -1; } int Minkowski(Point *A, int n, Point *B, int m, Point *C){ int t = 0, x = 1, y = 1; C[t++] = A[0] + B[0]; A[n] = A[0], B[m] = B[0]; while (x <= n && y <= m) if ( ((A[x]-A[x-1]) ^ (B[y]-B[y-1])) > 0) C[t] = C[t-1] + A[x] - A[x-1], t ++, x ++; else C[t] = C[t-1] + B[y] - B[y-1], t ++, y ++; while (x <= n) C[t] = C[t-1] + A[x] - A[x-1], t ++, x ++; while (y <= m) C[t] = C[t-1] + B[y] - B[y-1], t ++, y ++; return t - 1; } ll Area(Point *p, int n) { p[n] = p[0]; ll area = 0; for (int i = 1; i < n-1; ++ i) { area += cro(p[0], p[i], p[i+1]); } return area; } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); int n, m; scanf("%d%d", &n, &m); for (int i = 0; i < n; ++ i) A[i].input(); for (int i = 0; i < m; ++ i) B[i].input(); n = ConvexHull(A, n, C); memcpy(A, C, sizeof(Point)*(n)); m = ConvexHull(B, m, C); memcpy(B, C, sizeof(Point)*(m)); int p = Minkowski(A, n, B, m, C); printf("%lld\n", Area(C, p)); return 0; }