hdu 4052 Adding New Machine 扫描线求矩形面积并

原创 2013年12月04日 15:04:52

这个每一个矩形都确定了一个不能放的矩形空间,那么就是可以转化成求矩形面积并了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#define ll long long
#define midt (tr[t].l+tr[t].r>>1)
#define ls t<<1
#define rs t<<1|1
using namespace std;
const int maxn=7e4+9;
int w,h,n,m;
int y[maxn<<2],lon;
struct
{
    int xl,xu,yl,yu;
}rec[maxn],now[maxn<<1];

struct D
{
    int x,y1,y2,count;
    bool operator <(const D &xx) const
    {
        if(x!=xx.x) return(x<xx.x);
        else return count>xx.count;
    }
}d[maxn<<1];

struct
{
    int l,r,y1,y2,count,len;
}tr[maxn<<5];

void maketree(int t,int l,int r)
{
    tr[t].l=l;
    tr[t].r=r;
    tr[t].y1=y[l];
    tr[t].y2=y[r];
    tr[t].len=0;
    tr[t].count=0;
    if(l+1==r) return ;

    int mid=midt;
    maketree(ls,l,mid);
    maketree(rs,mid,r);
}

void insert(int t,int y1,int y2,D &d)
{
    if(tr[t].y1==y1&&tr[t].y2==y2)
    {
        tr[t].count+=d.count;
    }
    else
    {
        int mid=midt;
        if(y2<=y[mid])
        insert(ls,y1,y2,d);
        else if(y[mid]<=y1)
        insert(rs,y1,y2,d);
        else
        {
            insert(ls,y1,y[mid],d);
            insert(rs,y[mid],y2,d);
        }
    }
    if(tr[t].count>0) tr[t].len=tr[t].y2-tr[t].y1;
    else if(tr[t].l+1==tr[t].r) tr[t].len=0;
    else tr[t].len=tr[ls].len+tr[rs].len;
}

ll solve()
{
    set <int> s;
    s.clear();
    for(int i=1;i<=n;i++)
    {
        d[i*2-1].x=now[i].xl;
        d[i*2-1].y1=now[i].yl;
        d[i*2-1].y2=now[i].yu;
        d[i*2-1].count=1;

        d[i*2].x=now[i].xu;
        d[i*2].y1=now[i].yl;
        d[i*2].y2=now[i].yu;
        d[i*2].count=-1;

        s.insert(now[i].yl);
        s.insert(now[i].yu);
    }
    lon=0;
    for(set <int> ::iterator k=s.begin();k!=s.end();k++)
    {
        y[++lon]=*k;
    }

    if(lon==0) return 0;
    sort(d+1,d+1+n+n);

    maketree(1,1,lon);
    ll ans=0;
    d[0].x=-1;
    for(int i=1;i<=n*2;i++)
    {
        if(d[i].y1<=d[i].y2)
        {
            ans+=(ll)(d[i].x-d[i-1].x)*tr[1].len;
            insert(1,d[i].y1,d[i].y2,d[i]);
        }
    }
    return ans;
}

int main()
{
//    freopen("in.txt","r",stdin);
    while(scanf("%d%d%d%d",&w,&h,&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&rec[i].xl,&rec[i].yl);
            scanf("%d%d",&rec[i].xu,&rec[i].yu);
            rec[i].xl--;
            rec[i].yl--;
        }
        for(int i=1;i<=n;i++)
        {
            now[i].xl=max(0,rec[i].xl-m+1);
            now[i].xu=min(rec[i].xu,w-m+1);
            now[i].yl=rec[i].yl;
            now[i].yu=rec[i].yu;
        }
        ll ret=0;
        if(w-m+1>0)
        ret+=solve();

        for(int i=1;i<=n;i++)
        {
            now[i].xl=rec[i].xl;
            now[i].xu=rec[i].xu;
            now[i].yl=max(0,rec[i].yl-m+1);
            now[i].yu=min(rec[i].yu,h-m+1);
        }
        if(h-m+1>0)
        ret+=solve();


        ret=max((ll)(w-m+1)*h,(ll)0)+max((ll)w*(h-m+1),(ll)0)-ret;
        if(m==1)
        ret/=2;
        cout<<ret<<endl;
    }
    return 0;
}


【HDU4052】【ZOJ3540】Adding New Machine 线段树+扫描线

题意:W*H的格子上放着一些旧机器,现在要往图上放1*M的新机器,问放机器的方式有多少种 做法:把每个旧机器的范围扩展一下,向左&向下扩展m-1个格子,这样就转化为了求矩阵面积并的问题。同时要把矩形...
  • dizzz
  • dizzz
  • 2017年06月30日 22:14
  • 107

hdu4052Adding New Machine(线段树求矩形面积并)

题目请戳这里 题目大意:给一个w*h的矩阵,给n个矩形,n个矩阵互不相交。再给一个1*m的矩形,要求与给定的n个矩形不相交,求能摆放的方案种数。 题目分析:w和h很大,n有50000,所以离散化+线段...

hdu 4052 Adding New Machine

题意:给你W*H大小的矩形,其中有N个地区不能使用(给出了这个地区的两个顶点的坐标即(x1,y1)和(x2,y2)),问能下多少个1*M的矩形。 分别统计1*M的矩形横着放能放多少个,竖着放能放多少...

HDU - 1542 Atlantis(线段树扫描线求矩形并的面积)

HDU - 1542 Atlantis(线段树扫描线求矩形并的面积) 线段树求矩形面积详解 Problem Description There are several ancient Greek te...

HDU 1542 Atlantis(扫描线求矩形面积并+离散化)

http://acm.hdu.edu.cn/showproblem.php?pid=1542题意就是给n个矩形,这些矩形可能存在覆盖的地方,求矩形面积并。这种题目要用到扫描线,同时还要用到离散化(一时...

hdu4052-Adding New Machine-题解

扫描线,受到这里的启发。 注意充分利用不相交的条件。 我的代码没用线段树,用multiset过的。 // zoj3540 #include #include #include #inclu...

HDU 4052 Adding New Machine (线段树)

题意:有一个w*h的矩阵,里面放着n个矩形,现在有一个1*m的矩形要放置到这个矩形中,问有多少种放法。 思路:对于一种放法,只要求出可以放置矩形的起点组成的面积就行,那么我们可以把这个问题转化为求矩...

hdu 4052 Adding New Machine,set

hdu4052 Adding New Machine,set 比较老的题。给一个矩形和一些已经覆盖了的小矩形,问在剩余的空格上放一个长为m的条有多少种放法。 可以用线段树化为矩形面积并搞。这里...

线段树求矩形面积并 方法详解 (扫描线)HDU 1542 & HDU 3265 & POJ 1151

线段树求矩形面积并 方法详解 (扫描线)HDU 1542 & HDU 3265 & POJ 1151

算法总结:【线段树+扫描线】&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828)

问题:给出若干个矩形,(给的是矩形左上角和右下角坐标),求最后所得图形的面积/周长; 三个矩形如左图所示,而若要计算面积,看右图,用3个矩形各自的面积之和减去重复部分(红色和蓝色)的面积 人算很简单...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu 4052 Adding New Machine 扫描线求矩形面积并
举报原因:
原因补充:

(最多只允许输入30个字)