做法和上一篇的那個題一樣,每次刪掉一個點把相應的面積加上即可,不過細節問題折騰了我一個下午,所幸AC了,不過代碼已使我目不忍視了。
刪點的時候需要考慮左右交界處要加上的是一個三角形還是兩個三角形 ,各種細節改天附圖說明,今天已經廢了
貼上代碼,有少量debug用的資料
/* 0 0 -1 0 0 -1 2 0 -2 1 0 4 1 0 0 3 3 2 5 1 2 2 1 3 0 2 3 0 1 0 0 1 1 2 0 4 1 0 0 2 1 2 2 2 2 4 6 8 0 1 1 0 2 0 3 0 0 3 0 1 -1 2 3 6 0 0 1 1 2 0 4 1 -1 -1 0 1 2 3 0 4 6 9 12 */
#include <cstdio>#include <map>#include <set>#include <vector>#include <queue>#include <cmath>#include <iostream>#include <algorithm>using namespace std;const int maxn = 100010;typedef pair<int, int> pii;typedef long long lld;#define two(i) (lld)1<<i;#define MP make_pair#define X first#define Y secondmap<int, int>::iterator it, p, q;map<int, int> convex[2];lld sum;lld cross(pii a, pii b, pii c) { return (lld) (b.X - a.X) * (c.Y - a.Y) - (lld) (b.Y - a.Y) * (c.X - a.X);}bool judge(map<int, int> &st, int x, int y) { if (!st.size()) return false; if (st.find(x) != st.end()) return y >= st[x]; if (x < st.begin()->X || (--st.end())->X < x) return false; it = st.lower_bound(x); p = q = it; p--; return cross(MP(x, y), *q, *p) <= 0;}void insert(map<int, int> &st, int x, int y) { if (judge(st, x, y)) return; if (st.size() < 2) { st[x] = y; return; } it = st.lower_bound(x); q = p = it; if (it != st.end()) { if (it == st.begin()) { q++; if (it->X == x) sum += cross(MP(x, y), *q, *it); } else { p--; q++; sum += (cross(MP(x, y), *it, *p)); if (it->X == x && q != st.end()) sum += cross(MP(x, y), *q, *it); } } st[x] = y; it = st.find(x); lld tmp; for (; it != st.begin();) { p = it; p--; if (p == st.begin()) break; q = p; q--; if ((tmp = cross(*it, *p, *q)) >= 0) { sum += tmp; st.erase(p); } else break; } while (true) { p = it; p++; if (p == st.end()) break; q = p; q++; if (q == st.end()) break; if ((tmp = cross(*it, *p, *q)) <= 0) { sum += -tmp; st.erase(p); } else break; }}lld Abs(lld a) { if (a < 0) a = -a; return a;}void special(int x, int y) { // 上凸包與下凸包的交界處 , 如果是一條豎直的線,就需要特判了 int ax = (--convex[0].end())->X; int bx = (--convex[1].end())->X; if (ax == bx && x > ax) { p = --convex[0].end(); q = --convex[1].end(); sum += Abs(cross(MP(x, y), *p, MP(q->X, -q->Y))); } ax = (convex[0].begin())->X; bx = convex[1].begin()->Y; if (ax == bx && x < ax) { p = convex[0].begin(); q = convex[1].begin(); sum += Abs(cross(MP(x, y), *p, MP(q->X, -q->Y))); }}int main() { int n, x, y; sum = 0; int xx[3], yy[3]; for (int i = 0; i < 3; i++) { scanf("%d%d", &x, &y); xx[i] = x; yy[i] = y; insert(convex[0], x, y); insert(convex[1], x, -y); } sum = Abs(cross(MP(xx[0], yy[0]), MP(xx[1], yy[1]), MP(xx[2], yy[2]))); scanf("%d", &n); while (n--) { scanf("%d%d", &x, &y); special(x, y); insert(convex[0], x, y); insert(convex[1], x, -y); printf("%lld\n", sum); } return 0;}