Description:
随着改革开放的深入推进……
小T家要拆迁了……
当对未来生活充满美好憧憬的小T看到拆迁协议书的时候,小T从一位大好的社会主义青年变成了绝望的钉子户。
由于小T的家位于市中心,拆迁工作又难以进行,有关部门决定先把小T家用围栏围起来,以免影响市容。考虑到要建设资源节约型社会,他们希望所用的围栏长度越短越好,由于市中心寸土寸金,在围栏长度最短的情况下,围出的多边形面积越小越好。
为了简化问题,我们约定,小T的家是一个多边形,并且每条边与坐标轴平行,围栏构成的也是多边形,每条边与坐标轴平行。
4≤n≤100000
题解:
周长就不用说了吧……
面积可以想象是把四个角缩起来。
具体的话,按y拍个序,从上到下扫,维护左右区间的最大值,倒着扫一遍,同样利用差分维护一下值,最后减去原矩形面积就是答案。
正确性读者可以自己画个图搞搞。
Code:
#include<cstdio>
#include<algorithm>
#define ll long long
#define fo(i, x, y) for(ll i = x; i <= y; i ++)
#define fd(i, x, y) for(ll i = x; i >= y; i --)
using namespace std;
const ll N = 1e5 + 5;
ll n, c, s;
struct node {
ll x, y;
} a[N * 2];
ll up, down, left, right;
bool pd(node a, node b) {
return a.y < b.y;
}
ll l, r;
int main() {
scanf("%lld", &n);
fo(i, 1, n) scanf("%lld %lld", &a[i].x, &a[i].y);
sort(a + 1, a + n + 1, pd);
up = right = -1e9; down = left = 1e9;
fo(i, 1, n) {
up = max(up, a[i].y); down = min(down, a[i].y);
left = min(left, a[i].x); right = max(right, a[i].x);
}
c = (right - left + up - down) * 2;
l = 1e9; r = -1e9;
fo(i, 1, n) {
if(i != 1 && a[i - 1].y != a[i].y)
s += (r - l) * (a[i].y - a[i - 1].y);
l = min(l, a[i].x);
r = max(r, a[i].x);
}
l = 1e9; r = -1e9;
fd(i, n, 1) {
if(i != n && a[i + 1].y != a[i].y)
s += (r - l) * (a[i + 1].y - a[i].y);
l = min(l, a[i].x);
r = max(r, a[i].x);
}
s -= (right - left) * (up - down);
printf("%lld\n%lld\n", c, s);
}