HDU1542矩形面积并

取出纵向边按x坐标排序,在y方向上建立线段树。

每次查询当前有效长度len,ans += len*(x[i]-x[i-1]); 其中len为T[rt].len;

查询完毕后更新y方向上线段树,入边+1, 出边-1。

#include<bits/stdc++.h>
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
typedef long long ll;
struct L{
    double x, y1, y2;
    int d;
    L(){}
    L(double x, double y1, double y2, int d): x(x), y1(y1), y2(y2), d(d){}
};
L line[500];
bool cmp(L A, L B){
    return A.x < B.x;
}
double y[500];

struct Node{
    int d;
    double len;
};
Node T[500<<3];
void init(){
    memset(T, 0, sizeof(T));
}
void pushup(int rt, int l, int r){
    if(T[rt].d)
        T[rt].len = y[r]-y[l-1];
    else
        T[rt].len = l == r? 0 : T[rt<<1].len+T[rt<<1|1].len;
}
void update(int L, int R, int d, int l, int r, int rt){
    if(L <= l&&r <= R){
        T[rt].d += 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, ca = 1;
    double x1, y1, x2, y2;
    while(scanf("%d", &n), n){
        for(int i = 0; i < n; i++){
            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
            line[i*2] = L(x1, y1, y2, 1);
            line[i*2+1] = L(x2, y1, y2, -1);
            y[i*2] = y1, y[i*2+1] = y2;
        }
        sort(line, line+2*n, cmp);
        sort(y, y+2*n);

        init();
        double ans = 0, lastx = line[0].x;
        for(int i = 1; i < 2*n; i++){
            if(i&&line[i].x != line[i-1].x)
                ans += (line[i].x-line[i-1].x)*T[1].len;
            int l = lower_bound(y, y+2*n, line[i].y1)-y+1, r = lower_bound(y, y+2*n, line[i].y2)-y;
            if(l <= r)
                update(l, r, line[i].d, 1, 2*n, 1);
        }
        printf("Test case #%d\n", ca++);
        printf("Total explored area: %.2f\n\n", ans);
    }
    return 0;
}

无pushdown()函数,每条线段只存一次。d表示被覆盖的次数,len表示至少被覆盖一次的合法长度。详见pushup()函数。

ans += T[1].len*(x[i]-x[i-1]);

求面积交:方法同求面积并,外加len2表示至少被覆盖两次的合法长度,ans += T[1].len2*(x[i]-x[i-1]);

求周长并:方法同面积并,扫描两次,分别沿x方向和y方向,每次加上  更新前后T[1].len的差值的绝对值。

时间: 2024-12-06 21:41:37

HDU1542矩形面积并的相关文章

HDU1542 矩形面积并 扫描线段树

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 题意:二维平面有n个平行于坐标轴的的矩形,要算矩形面积并 有一个讲的很好的博客:https://blog.csdn.net/u013480600/article/details/22548393 线段树是按叶节点来一个个维护的,一堆浮点数是不能直接维护的,需要离散化来维护. 要注意我们线段树中每个叶节点(控制区间[L,L])不是指X[L]坐标,而是指区间[X[L],X[L+1]].线段树中其他

HDU1542 扫描线(矩形面积并)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 18275    Accepted Submission(s): 7409 Problem Description There are several ancient Greek texts that contain descriptions of the fabled i

25.按要求编写一个Java应用程序: (1)编写一个矩形类Rect,包含: 两个属性:矩形的宽width;矩形的高height。 两个构造方法: 1.一个带有两个参数的构造方法,用于将width和height属性初化; 2.一个不带参数的构造方法,将矩形初始化为宽和高都为10。 两个方法: 求矩形面积的方法area() 求矩形周长的方法perimeter() (2)通过继承Rect类编写一个具有

package zhongqiuzuoye; public class Rect { public double width; public double height; Rect(double width,double height) //带有两个参数的构造方法,用于将width和height属性初化; { this.width=width; this.height=height; } Rect() //不带参数的构造方法,将矩形初始化为宽和高都为10. { width=10; height=

HDU 1542 Atlantis (求矩形面积并)

Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of

HDU 1255 覆盖的面积 (求矩形面积的交)

覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input 输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个

相邻最大矩形面积的问题

9715 相邻最大矩形面积 时间限制:1000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC;VC;JAVA Description 在X轴上水平放置着 N 个条形图,这 N 个条形图就组成了一个柱状图,每个条形图都是一个矩形,每个 矩形都有相同的宽度,均为1单位长度,但是它们的高度并不相同. 例如下图,图1包含的矩形的高分别为2,1,4,5,1,3,3 单位长度,矩形的宽为1单位长度. 你的任务就是计算柱状图中以X轴为底边的最大矩形的面积.

计算直方图中最大矩形面积

题目是计算直方图中的最大矩形面积,下面是我的做法,我在网上也看到有人说可以通过栈的方式来解决,因为时间问题,并没有马上尝试,下回有时间在尝试下吧!! 还有这题有变式:计算矩阵中最大的矩形面积,其中矩阵中元素只能为1和0,代码下次补发吧!! 代码如下: #include<iostream>using namespace std; int maxSquare(const int pos,const int n,const int height[]){ if(n==1) return height[

【最小矩形面积覆盖:凸包+旋转卡壳】UVA 10173 Smallest Bounding Rectangle

[最小矩形面积覆盖:凸包+旋转卡壳]UVA 10173 Smallest Bounding Rectangle 题目链接:UVA 10173 Smallest Bounding Rectangle 题目大意 给你n个点,求能够覆盖所有点集的最小矩形面积. 笔者的第2道凸包题目,凸包 + 旋转卡壳,实现点集的最小矩形面积覆盖问题 ">=0"写成"<=0"坑了我一下午!QAQ 说一下思路 ①Graham's Scan法构建凸包,时间复杂度O(nlogn) ②

hdu 1505 City Game 最大矩形面积 单调队列

City Game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5106    Accepted Submission(s): 2197 Problem Description Bob is a strategy game programming specialist. In his new city building game t