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 }

        

  • 相关阅读:
    jsp 特殊标签
    poj 1753 Flip Game 高斯消元 异或方程组 求最值
    zoj 3155 Street Lamp 高斯消元 异或方程组 求方案数
    poj1222 EXTENDED LIGHTS OUT 高斯消元解异或方程组 模板
    zoj 3930 Dice Notation 模拟
    zoj 3157 Weapon 线段树求逆序对数
    hdu 1242 Rescue BFS+优先队列
    hdu 3466 Proud Merchants 贪心+01背包
    zoj 3689 Digging 贪心+01背包
    hdu 2602 Bone Collector 01背包模板
  • 原文地址:https://www.cnblogs.com/kane0526/p/2935340.html
Copyright © 2011-2022 走看看