http://acm.hdu.edu.cn/showproblem.php?pid=1542

单纯的线段树+扫描线求面积并,需要离散化。

code:

#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <iomanip>
#include <bitset>
#include <list>
#include <ctime>
using namespace std ;

#define SET(arr, what)  memset(arr, what, sizeof(arr))
#define FF(i, a)        for(i=0; i<a; i++)
#define SD(a)           scanf("%d", &a)
#define SSD(a, b)       scanf("%d%d", &a, &b)
#define SSF(a, b)       scanf("%lf%lf", &a, &b)
#define SS(a)           scanf("%s", a)
#define SLD(a)          scanf("%lld", &a)
#define PF(a)           printf("%d\n", a)
#define PPF(a, b)       printf("%d %d\n", a, b)
#define PLF(a)          printf("%lf\n", a)
#define SZ(arr)         (int)a.size()
#define SWAP(a,b)       a=a xor b;b= a xor b;a=a xor b;
#define read            freopen("in.txt", "r", stdin)
#define write            freopen("out.txt", "w", stdout)
#define MAX             1<<30
#define ESP             1e-5
#define lson            l, m, rt<<1
#define rson            m+1, r, rt<<1|1
template<class T> inline T sqr(T a){return a*a;}
template<class T> inline void AMin(T &a,T b){if(a==-1||a>b)a=b;}
template<class T> inline void AMax(T &a,T b){if(a<b)a=b;}
template<class T> inline T Min(T a,T b){return a>b?b:a;}
template<class T> inline T Max(T a,T b){return a>b?a:b;}
const int maxn = 2222 ;
int cover[maxn<<2] ;
double sum[maxn<<2], s[maxn] ;
struct Seg{
    double l, r, h ;
    int d ;
}seg[maxn] ;
int cmp1(const void *a, const void *b){
    return (*(Seg *)a).h < (*(Seg *)b).h ? -1 : 1 ;
}
int cmp2(const void *a, const void *b){
    return *(double *)a < *(double *)b ? -1 : 1 ;
}
void setSeg(double l, double r, int d, double h, int cnt){
    seg[cnt].l = l ;
    seg[cnt].r = r ;
    seg[cnt].d = d ;
    seg[cnt].h = h ;
}
void pushup(int rt, int l, int r){
    if(cover[rt])   sum[rt] = s[r+1] - s[l] ;
    else if(l==r)   sum[rt] = 0 ;
    else            sum[rt] = sum[rt<<1] + sum[rt<<1|1] ;
}
int find(double val, int r){
    int l = 0 ;
    while(l<=r){
        int m = (l + r) >> 1 ;
        if(val==s[m])   return m ;
        if(val>s[m]) l = m + 1 ;
        else    r = m - 1 ;
    }
    return -1 ;
}
void update(int L, int R, int d, int l, int r, int rt){
    if(L<=l&&r<=R){
        cover[rt] += d ;
        pushup(rt, l, r) ;
        return ;
    }
    int m = (l + r) >> 1 ;
    if(L<=m)    update(L, R, d, lson) ;
    if(R>m)     update(L, R, d, rson) ;
    pushup(rt, l, r) ;
}
int main(){
    int n, t=1, i, x, y, j, m ;
    double a, b, c, d, ans ;
    while(~SD(n)&&n){
        x = y = 0 ;
        FF(i, n){
            SSF(a, b) ;SSF(c, d) ;
            s[y++] = a ;
            s[y++] = c ;
            setSeg(a, c, 1, b, x++) ;
            setSeg(a, c, -1, d, x++) ;
        }
        qsort(seg, x, sizeof(Seg), cmp1) ;
        qsort(s, x, sizeof(double), cmp2) ;
        m = 1 ;
        for(i=1; i<y; i++)  if(s[i]!=s[i-1])    s[m++] = s[i] ;
        SET(sum, 0) ;
        SET(cover, 0) ;
        ans = 0 ;
        FF(i, x-1){
            int l = find(seg[i].l, m-1) ;
            int r = find(seg[i].r, m-1) - 1 ;
            if(l<=r)    update(l, r, seg[i].d, 0, m-1, 1) ;
            ans += sum[1] * (seg[i+1].h - seg[i].h) ;
        }
        printf("Test case #%d\n", t++) ;
        printf("Total explored area: %.2lf\n\n", ans) ;
    }
    return 0 ;
}

转载于:https://www.cnblogs.com/xiaolongchase/archive/2012/08/22/2650187.html

hdu 1542 Atlantis (线段树+扫描线)相关推荐

  1. HDU - 1542 Atlantis(线段树+扫描线)

    题目链接:点击查看 题目大意:给出n个矩形的左下角坐标和右上角坐标,求出其总面积,注意,矩形会重叠,重叠部分只计算一次 题目分析:如果暴力做需要考虑容斥原理,两两矩形组合判断是否重合,十分麻烦而且时间 ...

  2. HDU 1542 Atlantis 线段树+离散化+扫描线

    题意:给出一些矩形的最上角坐标和右下角坐标,求这些矩形的面积并. NotOnlySuccess 线段树专辑中扫描线模板题,弱智的我对着大大的代码看了一下午才搞懂. 具体见思路见注释=.= #inclu ...

  3. POJ 1151 Atlantis 线段树+扫描线

    解题思路: 先将y轴进行离散化.n个矩形的2n个横边纵坐标共构成最多2n-1个区间的边界,对这些区间编号,建立起线段树. x轴记录左边和右边,左边时是矩形面积增加,覆盖层数增加边,右边是形面积减少,覆 ...

  4. HDU 1828 Picture 线段树 扫描线

    写完后才发现数据是int不是double... //#pragma comment(linker, "/STACK:1024000000,1024000000") #include ...

  5. HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)

    版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...

  6. 线段树扫描线求矩形周长详解

    线段树扫描线求矩形周长详解 原创 wucstdio 最后发布于2018-04-24 16:12:09 阅读数 841 收藏 发布于2018-04-24 16:12:09 版权声明:本文为博主原创文章, ...

  7. hdu3255 线段树扫描线求体积

    题意:       给你n个矩形,每个矩形上都有一个权值(该矩形单位面积的价值),矩形之间可能重叠,重叠部分的权值按照最大的算,最后问这n个矩形组成的图形的最大价值. 思路:       线段树扫描线 ...

  8. hdu1542 线段树扫描线求矩形面积的并

    题意:       给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路:       自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...

  9. HDU 2795 Billboard (线段树+贪心)

    HDU 2795 Billboard (线段树+贪心) 手动博客搬家:本文发表于20170822 21:30:17, 原地址https://blog.csdn.net/suncongbo/articl ...

最新文章

  1. html css 学习笔记(1)背景相关
  2. PHP公鸡五文钱,公鸡
  3. 排序算法第一篇——插入排序
  4. oracle暂停索引,Oracle索引被抑制情况
  5. Hibernate dbcp连接池使用方法
  6. Q111:PBRT-V3系统概述
  7. java程序员必须会的技能
  8. 哈希库--uthash的详细讲解(附uthash相关头文件下载)
  9. python rtf读取_如何使用Python读取RTF文件,python,格式,的
  10. 一分钟教你解决——浏览器代理服务器被篡改
  11. Wargames学习笔记--Natas
  12. 九龙证券|大宗商品集体下挫,黄金一枝独秀,纳指领跑全球股市
  13. 181124 逆向-2018“柏鹭杯”厦大邀请赛初赛(Re1、2)
  14. 职场人士需了解:职场文件删除了三种恢复方法
  15. 【入门】【递推】走楼梯
  16. 老调重弹之ffmpeg视频时间同步
  17. Linux定时运行Python脚本
  18. Web安全 DDoS攻击.(让网站无法正常地提供服务.)
  19. .Net Reflector反编译代码与源代码的区别
  20. 中国版权保护中心-无法注册的解决办法

热门文章

  1. 靠谱测试人员需具备解决问题能力
  2. c语言中验证巴德哥赫猜想,哥赫巴德猜想具体内容是什么?
  3. 学软件测试看什么书籍推荐?
  4. Docker框架的使用系列教程(一)
  5. dw2019连接mysql数据库_VS2019连接mysql8.0数据库的教程图文详解
  6. Linux权限z代表什么,linux用户与权限使用方法
  7. 同一字段降序个升序_5个打印小技巧,表格打印没烦恼
  8. html颜色对话框,网页颜色对话框的使用
  9. STM8单片机ADC模拟看门狗功能实现
  10. centos7.5 安装配置supervisor管理python进程(也就是服务)