题目链接: http://poj.org/problem?id=1177
---------------------------------------------------------------------------------------
矩形并的周长模板题 建议先做了矩形面积并后再来做这题
代码可以直接在矩形面积并的基础上修改
我们假设扫描线是平行于$y$轴的
$sum$数组为这一段被覆盖的长度 $cnt$数组为这一段覆盖的段数
那么平行于$y$轴的周长可以直接利用$sum$数组变化的绝对值累加
而平行于$x$轴的周长则可以利用向右移动时的长度乘上$cnt$数组再乘$2$得到
注意一个矩形入边和另一个矩形出边重合的问题
这里可以在排序时将入边排在前面避免统计出错
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 const int N = 5010; 7 struct rec 8 { 9 int xa, ya, xb, yb; 10 }a[N]; 11 struct line 12 { 13 int x, ya, yb, num; 14 }b[N << 1]; 15 int hash[N << 1]; 16 int sum[N << 3], flag[N << 3]; 17 int cnt[N << 3], pl[N << 3], pr[N << 3]; 18 int n, ans; 19 bool cmp(const line &aa, const line &bb) 20 { 21 return aa.x < bb.x || (aa.x == bb.x && aa.num > bb.num); 22 } 23 void pushup(int x, int tl, int tr) 24 { 25 if(flag[x]) 26 { 27 sum[x] = hash[tr + 1] - hash[tl]; 28 cnt[x] = 1; 29 pl[x] = pr[x] = 1; 30 } 31 else if(tl != tr) 32 { 33 sum[x] = sum[x << 1] + sum[x << 1 | 1]; 34 cnt[x] = cnt[x << 1] + cnt[x << 1 | 1] - 35 (pr[x << 1] && pl[x << 1 | 1]); 36 pl[x] = pl[x << 1]; 37 pr[x] = pr[x << 1 | 1]; 38 } 39 else 40 sum[x] = cnt[x] = pl[x] = pr[x] = 0; 41 } 42 void update(int x, int L, int R, int tl, int tr, int num) 43 { 44 if(L <= tl && tr <= R) 45 { 46 flag[x] += num; 47 pushup(x, tl, tr); 48 return; 49 } 50 int mid = (tl + tr) >> 1; 51 if(L <= mid) 52 update(x << 1, L, R, tl, mid, num); 53 if(mid < R) 54 update(x << 1 | 1, L, R, mid + 1, tr, num); 55 pushup(x, tl, tr); 56 } 57 int main() 58 { 59 scanf("%d", &n); 60 for(int i = 1; i <= n; ++i) 61 { 62 scanf("%d%d%d%d", &a[i].xa, &a[i].ya, &a[i].xb, &a[i].yb); 63 b[i * 2 - 1].x = a[i].xa; 64 b[i * 2 - 1].num = 1; 65 b[i * 2].x = a[i].xb; 66 b[i * 2].num = -1; 67 b[i * 2 - 1].ya = b[i * 2].ya = a[i].ya; 68 b[i * 2 - 1].yb = b[i * 2].yb = a[i].yb; 69 hash[i * 2 - 1] = a[i].ya; 70 hash[i * 2] = a[i].yb; 71 } 72 sort(b + 1, b + 1 + n * 2, cmp); 73 sort(hash + 1, hash + 1 + n * 2); 74 int L, R, lastsum = 0; 75 b[0].x = b[1].x; 76 for(int i = 1; i <= n * 2; ++i) 77 { 78 ans += (b[i].x - b[i - 1].x) * cnt[1] * 2; 79 L = lower_bound(hash + 1, hash + 1 + n * 2, b[i].ya) - hash; 80 R = lower_bound(hash + 1, hash + 1 + n * 2, b[i].yb) - hash - 1; 81 update(1, L, R, 1, n * 2 - 1, b[i].num); 82 ans += abs(sum[1] - lastsum); 83 lastsum = sum[1]; 84 } 85 printf("%d ", ans); 86 return 0; 87 }