HDU 1264 Counting Squares(线段树求面积的并)

Counting Squares

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1885    Accepted Submission(s): 946

Problem Description

Your input is a series of rectangles, one per line. Each rectangle is specified as two points(X,Y) that specify the opposite corners of a rectangle. All coordinates will be integers in the range 0 to 100. For example, the line
5 8 7 10
specifies the rectangle who‘s corners are(5,8),(7,8),(7,10),(5,10).
If drawn on graph paper, that rectangle would cover four squares. Your job is to count the number of unit(i.e.,1*1) squares that are covered by any one of the rectangles given as input. Any square covered by more than one rectangle should only be counted once.

Input

The input format is a series of lines, each containing 4 integers. Four -1‘s are used to separate problems, and four -2‘s are used to end the last problem. Otherwise, the numbers are the x-ycoordinates of two points that are opposite corners of a rectangle.

Output

Your output should be the number of squares covered by each set of rectangles. Each number should be printed on a separate line.

Sample Input

5 8 7 10
6 9 7 8
6 8 8 11
-1 -1 -1 -1
0 0 100 100
50 75 12 90
39 42 57 73
-2 -2 -2 -2

Sample Output

8
10000

题目链接:HDU 1264

连离散化都不用的水题,有一个坑点就是题目给的两个对角线坐标不一定是左下、右上这样一个顺序,或者也可能是副对角线上的点,需要判断一下

代码:

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int N=1e3+7;
struct seg
{
    int l,mid,r;
    int cnt,len;
};
struct Line
{
    int l,r,h,flag;
    bool operator<(const Line &t)const
    {
        return h<t.h;
    }
};
seg T[N<<3];
Line xline[N<<1];

inline void pushup(int k)
{
    if(T[k].cnt>0)
        T[k].len=T[k].r-T[k].l+1;
    else
    {
        if(T[k].l==T[k].r)
            T[k].len=0;
        else
            T[k].len=T[LC(k)].len+T[RC(k)].len;
    }
}
void build(int k,int l,int r)
{
    T[k].l=l;
    T[k].r=r;
    T[k].mid=MID(l,r);
    T[k].len=T[k].cnt=0;
    if(l==r)
        return ;
    build(LC(k),l,T[k].mid);
    build(RC(k),T[k].mid+1,r);
    pushup(k);
}
void update(int k,int l,int r,int flag)
{
    if(l<=T[k].l&&T[k].r<=r)
    {
        T[k].cnt+=flag;
        pushup(k);
    }
    else
    {
        if(r<=T[k].mid)
            update(LC(k),l,r,flag);
        else if(l>T[k].mid)
            update(RC(k),l,r,flag);
        else
            update(LC(k),l,T[k].mid,flag),update(RC(k),T[k].mid+1,r,flag);
        pushup(k);
    }
}
int main(void)
{
    int n,i;
    int xa,ya,xb,yb;
    int cnt=0;
    while (scanf("%d%d%d%d",&xa,&ya,&xb,&yb))
    {
        if(xa==-1&&xb==-1&&ya==-1&&yb==-1)
        {
            int ans=0;
            build(1,0,N);
            sort(xline,xline+cnt);
            for (i=0; i<cnt-1; ++i)
            {
                update(1,xline[i].l,xline[i].r-1,xline[i].flag);
                ans=ans+(xline[i+1].h-xline[i].h)*T[1].len;
            }
            printf("%d\n",ans);
            cnt=0;
        }
        else if(xa==-2&&xb==-2&&ya==-2&&yb==-2)
        {
            int ans=0;
            build(1,0,N);
            sort(xline,xline+cnt);
            for (i=0; i<cnt-1; ++i)
            {
                update(1,xline[i].l,xline[i].r-1,xline[i].flag);
                int dh=(xline[i+1].h-xline[i].h);
                ans=ans+dh*T[1].len;
            }
            printf("%d\n",ans);
            cnt=0;
            break;
        }
        else
        {
            if(xa>xb)
                swap(xa,xb);
            if(ya>yb)
                swap(ya,yb);
            xline[cnt++]=(Line){xa,xb,ya,1};
            xline[cnt++]=(Line){xa,xb,yb,-1};
        }

    }
    return 0;
}
时间: 2024-08-02 19:41:15

HDU 1264 Counting Squares(线段树求面积的并)的相关文章

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

Problem A : Counting Squares From:HDU, 1264 Problem Description Your input is a series of rectangles, one per line. Each rectangle is specified as two points(X,Y) that specify the opposite corners of a rectangle. All coordinates will be integers in t

HDU 1542 Atlantis (线段树求矩阵覆盖面积)

题意:给你n个矩阵求覆盖面积. 思路:看了别人的结题报告 给定一个矩形的左下角坐标和右上角坐标分别为:(x1,y1).(x2,y2),对这样的一个矩形,我们构造两条线段,一条定位在x1,它在y坐标的区间是[y1,y2],并且给定一个cover域值为1:另一条线段定位在x2,区间一样是[y1,y2],给定它一个cover值为-1.根据这样的方法对每个矩形都构造两个线段,最后将所有的线段根据所定位的x从左到右进行排序 #include <iostream> #include <stdio.h

hdu 2665 可持久化线段树求区间第K大值(函数式线段树||主席树)

http://acm.hdu.edu.cn/showproblem.php?pid=2665 Problem Description Give you a sequence and ask you the kth big number of a inteval. Input The first line is the number of the test cases. For each test case, the first line contain two integer n and m (

HDU 1264 Counting Squares(Hash)或者(线段树+线扫描)

http://acm.hdu.edu.cn/showproblem.php?pid=1264 题意:给你矩形的左下角和右上角两个坐标,让你求这些矩形覆盖的面积的大小!~ 分析:一看就是线段树+线扫描的问题,其实如果你仔细看一下就会发现还有简单的方法解决它,因为题目所给的坐标值在0~100之间的整数, 这样我们就可以用Hash[][]来表示1*1矩形的个数,Hash[i][j]表示以坐标值(i,j)为左下角1*1的矩形是否被覆盖,这样我们就可以用Hash二维数组表示平面上1*1矩形个数. 注意:我

hdu(1255)——覆盖的面积(线段树求面积交)

给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 虽说覆盖两次区域的面积,但是这道题实际上就是求矩形的面积交. 膜拜能够想出这种解法的神牛,竟然能把实际的东西用这么抽象的语言表示出来,实在是佩服,现在关于扫描线的题才做了几道,没有对其深刻理解,但是多练总可以理解的,奋斗吧!!ACMer!!我是永远不会服输的.加油! 下面还是附上题解,写的不够详细清楚还请多多见谅. 首先我想说我是看了别人的博客学了思路,然后按照别人的代码来模仿写的. 这里推荐:http://www.cnblogs.

hdu 1542 Atlantis 线段树求面积并,,,尼玛数据真坑人,数组千万不能开小!

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

HDU 1394- Minimum Inversion Number(线段树求逆序数)

Minimum Inversion Number Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1394 Appoint description:  System Crawler  (2015-04-13) Description The inversion number of a given number sequence a1, a

HDU-1255-覆盖的面积-线段树求面积并(模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 好吧,这题和HDU1542几乎完全一样,链接:http://blog.csdn.net/wlxsq/article/details/47254571我有详细讲: 这个题目唯一的不同就是这是个求重合的面积,而HDU1542是求并面积,如果明白了1542题目的原理,我想很轻松的就可以搞定这个题目,只要将cover>0改成cover>1就可以求出覆盖面积了,我这里就不在赘述了:代码我再贴一下 #i

HDU 1542 Atlantis(线段树扫描线&#183;面积并)

题意  给你一些矩形的左下和右上的坐标  求这些矩形的面积并 最基础的扫描线  理解了就是个水题了  先看一些图吧                                恩  看完了有什么感觉没有  那些红色的线就可以当作传说中的扫描线  就像从左到右扫描嘛  可以发现  矩形有竖直边的地方就有这些线  这些线把把拼在一起的矩形切成了一个个的小矩形  我们把这些小矩形的面积加起来不就是要求的面积吗 那么现在这些小矩形的面积怎么求呢  长乘宽嘛  长是什么  两条红线之间的距离  恩  我