POJ 1177 Picture

题目链接: 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\n", ans);
86     return 0;
87 }

 

posted @ 2016-02-05 18:07  sagitta  阅读(347)  评论(0编辑  收藏  举报