用整形实现的。封装好了。就是不知道为什么有点慢。
code(373ms):
#include <iostream>
#include <set>
using namespace std;
#define DEBUG 0
typedef long long LL;
typedef LL LT;
template <typename T>
(T x) {
T sqreturn x * x;
}
int sgn(LT x) {
return x < 0 ? -1 : (x > 0 ? 1 : 0);
}
struct VEC {
, y;
LT x
operator + (const VEC& b) const {
VEC return VEC{x + b.x, y + b.y};
}
bool operator == (const VEC& b) const {
return x == b.x && y == b.y;
}
bool operator < (const VEC& b) const {
return y != b.y ? y < b.y : x < b.x;
}
operator - (const VEC& b) const {
VEC return VEC{x - b.x, y - b.y};
}
() const {
LT len2return sq(x) + sq(y);
}
(const VEC& b) const {
LT dist2return (*this - b).len2();
}
//Might overflow
operator * (const VEC& b) const {
LT return x * b.x + y * b.y;
}
operator ^ (const VEC& b) const {
LT return x * b.y - y * b.x;
}
bool ToLeftTest(const VEC& b) const {
return (*this ^ b) > 0;
}
bool ToRightTest(const VEC& b) const {
return (*this ^ b) < 0;
}
(const VEC& p1, const VEC& p2) const {
LT crossreturn (p1 - *this) ^ (p2 - *this);
}
void input() {
>> x >> y;
cin }
};
struct down_sgn {
int operator () (LT x) const {
return sgn(x);
}
};
struct up_sgn {
int operator () (LT x) const {
return -sgn(x);
}
};
template <class XSGN>
struct HalfConvexHull {
#define xsgn XSGN()
struct CMPX {
bool operator () (const VEC& a, const VEC& b) {
return xsgn(a.x - b.x) < 0;
}
};
typedef set<VEC, CMPX> SE;
;
SE stypedef typename SE::iterator IT;
; //to (0, 0)
LT area2;
IT it() : area2(0) {}
HalfConvexHull//The convex mustn't be degenerate
//0: out
//1: on
//2: in
int relation(const VEC& p) {
= s.lower_bound(p);
it if (it == s.end()) return 0;
if (it == s.begin()) {
if (xsgn(p.x - it->x) < 0) return 0;
else return xsgn(p.y - it->y) + 1;
}
auto bef = it;
--bef;
return sgn((*it - *bef) ^ (p - *bef)) + 1;
}
(IT it) {
IT Prereturn it == s.begin() ? s.end() : --it;
}
void Insert(const VEC& p) {
if (relation(p)) return;
bool del = false;
;
VEC dif (it != s.end() && it->x == p.x) {
= *it;
d = true;
del .erase(it);
s}
= s.insert(p).first;
it auto pre = Pre(it);
auto nxt(it);
++nxt;
if (pre != s.end()) {
if (del) {
-= *pre ^ d;
area2 } else if (nxt != s.end()) {
-= *pre ^ *nxt;
area2 }
+= *pre ^ p;
area2 for (auto j = Pre(pre); j != s.end() && ((*pre - p) ^ (*j - p)) >= 0; pre = j, j = Pre(j)) {
+= (*j ^ p) - (*j ^ *pre) - (*pre ^ p);
area2 .erase(pre);
s}
}
if (nxt != s.end()) {
if (del) {
-= d ^ *nxt;
area2 }
+= p ^ *nxt;
area2 auto j = nxt;
for (++j; j != s.end() && ((*j - p) ^ (*nxt - p)) >= 0; nxt = j, ++j) {
+= (p ^ *j) - (p ^ *nxt) - (*nxt ^ *j);
area2 .erase(nxt);
s}
}
}
};
struct ConvexHull {
<down_sgn> down;
HalfConvexHull<up_sgn> up;
HalfConvexHullvoid Insert(const VEC& p) {
.Insert(p);
down.Insert(p);
up}
() const {
LT area2if (down.s.empty()) return 0;
return (*up.s.rbegin() ^ *down.s.begin()) + down.area2 +
(*down.s.rbegin() ^ *up.s.begin()) + up.area2;
}
};
int main() {
;
ConvexHull conv;
VEC p
::sync_with_stdio(false);
ios.tie(0);
cin.tie(0);
cout
int n = 3;
while (n--) {
.input();
p.Insert(p);
conv}
>> n;
cin while (n--) {
if (0 == n) {
= n * 2 / 2;
n }
.input();
p.Insert(p);
conv<< conv.area2() << endl;
cout }
return 0;
}