zoukankan      html  css  js  c++  java
  • 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
    ", ans);
    86     return 0;
    87 }
  • 相关阅读:
    Kudu-Impala集成特性
    [转]IIS的各种身份验证详细测试
    [转]The NTLM Authentication Protocol and Security Support Provider
    [转]WxEmojiView
    [转]Redis 数据类型
    [转]a-mongodb-tutorial-using-c-and-asp-net-mvc
    [转]MongoDB 概念解析
    [转]flash.net.Socket
    [转]emailjs-smtp-client
    [转]jquerUI Dialog中隐藏标题栏的关闭"X"按钮
  • 原文地址:https://www.cnblogs.com/sagitta/p/5183457.html
Copyright © 2011-2022 走看看