做法和上一篇的那个题一样,每次删掉一个点把相应的面积加上即可,不过细节问题折腾了我一个下午,所幸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 second
map<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;
}