zoukankan      html  css  js  c++  java
  • 【hdu 1828 Picture】 线段树之扫面线(周长并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1828

    题目大意: 给你多个矩形,求他们合并和的周长,被覆盖的边不能算进周长之内。

    解题思路:

         其实周长并和面积并没什么很大的区别,只不过周长并增加了判断左右端点是否被覆盖的标记 lbd 和rbd 数组, 以及numseg 数组 记录连续区间段数。

         numseg : 一根扫描线扫描过去,会记录有多少个连续的区间段,每个连续的区间段都有两条相等的竖边,而每次扫描过去竖边长度都相等。

         参考文献 :陈宏《数据结构的选择与算法效率》

    View Code
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 #define lz 2*u,l,mid
      8 #define rz 2*u+1,mid+1,r
      9 const int maxn=22222;
     10 int sum[4*maxn];              ///记录被覆盖区间的长度
     11 int lbd[4*maxn], rbd[4*maxn]; ///记录左右端点是否被覆盖
     12 int numseg[4*maxn];            ///记录该区间连续的段数
     13 int flag[4*maxn];              /// 记录该区间是否被覆盖
     14 
     15 struct Node
     16 {
     17     int lx, rx, y, s;
     18     int lbd, rbd;
     19     Node() {};
     20     Node(int lx_, int rx_, int y_, int s_)
     21     {
     22         lx=lx_, rx=rx_, y=y_, s=s_;
     23     }
     24     bool operator <(const Node &S) const
     25     {
     26         if(y==S.y) return s>S.s;
     27         return y<S.y;
     28     }
     29 } line[maxn];
     30 
     31 void push_up(int u, int l, int r)
     32 {
     33     if(flag[u])
     34     {
     35         lbd[u]=1;
     36         rbd[u]=1;
     37         sum[u]=r-l+1;
     38         numseg[u]=2;
     39     }
     40     else if(l==r)
     41     {
     42         sum[u]=numseg[u]=lbd[u]=rbd[u]=0;
     43     }
     44     else
     45     {
     46         lbd[u]=lbd[2*u];
     47         rbd[u]=rbd[2*u+1];
     48         sum[u]=sum[2*u]+sum[2*u+1];
     49         numseg[u]=numseg[2*u]+numseg[2*u+1];
     50         if(rbd[2*u]&&lbd[2*u+1]) numseg[u]-=2;
     51     }
     52 }
     53 
     54 void Update(int u, int l, int r, int tl, int tr, int c)
     55 {
     56     if(tl<=l&&r<=tr)
     57     {
     58         flag[u]+=c;
     59         push_up(u,l,r);
     60         return ;
     61     }
     62     int mid=(l+r)>>1;
     63     if(tr<=mid) Update(lz,tl,tr,c);
     64     else if(tl>mid) Update(rz,tl,tr,c);
     65     else
     66     {
     67         Update(lz,tl,mid,c);
     68         Update(rz,mid+1,tr,c);
     69     }
     70     push_up(u,l,r);
     71 }
     72 
     73 int main()
     74 {
     75     int n;
     76     while(cin >> n)
     77     {
     78         int x1, x2, y1, y2;
     79         int num=0, lbd=10000, rbd=-10000;
     80         for(int i=0; i<n; i++)
     81         {
     82             scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
     83             line[++num]=Node(x1,x2,y1,1);
     84             line[++num]=Node(x1,x2,y2,-1);
     85             lbd=min(lbd,x1);
     86             rbd=max(rbd,x2);
     87         }
     88         sort(line+1,line+num+1);
     89         int ans=0, last=0;
     90         for(int i=1; i<=num; i++)
     91         {
     92             Update(1,lbd,rbd-1,line[i].lx,line[i].rx-1,line[i].s);
     93             ans+=numseg[1]*(line[i+1].y-line[i].y);
     94             ans+=abs(sum[1]-last);
     95             last=sum[1];
     96         }
     97         cout << ans <<endl;
     98     }
     99     return 0;
    100 }

        

  • 相关阅读:
    通过scrapy内置的ImagePipeline下载图片到本地、并提取本地保存地址
    算法的时间复杂度和空间复杂度
    session cookie的区别最全总结
    汉明码(海明码)计算方法
    测试 markdown
    PHP扩展--opcache安装及配置
    PHP_EOL
    BUG:php7.1 访问yii数据库 自动加端口3306 报错
    BUG:upstream timed out (10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected
    图的遍历之 深度优先搜索和广度优先搜索
  • 原文地址:https://www.cnblogs.com/kane0526/p/2935340.html
Copyright © 2011-2022 走看看