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

#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;
}


• 本文已收录于以下专栏：

## HDU 4052 Adding New Machine（矩形面积并）

HDU 4052 Adding New Machine（矩形面积并） 题目大意： w*h的格子，现在有n个矩形上已经摆放了东西，现在你要放一个东西长度为m，问你有多少种方法？ 解题思路：...
• a1061747415
• 2014年10月04日 19:26
• 1050

## hdu 4052 Adding New Machine(线段树+扫描线)

• qian99
• 2014年05月03日 23:25
• 609

## hdu 4052 Adding New Machine

• shiqi_614
• 2012年09月16日 00:42
• 1544

## 矩形面积并、矩形面积交、矩形周长并（线段树、扫描线总结）

HDU 1542 [POJ 1151] Atlantis （矩形面积并） 题意: 求N
• lwt36
• 2015年10月05日 01:24
• 3871

## hdu 1542 矩形面积并（扫描线+线段树）

【题目链接】 http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=14795 【解题报告】 七月的时候做过扫描线线段树，那个时...
• gungnir0711
• 2015年12月16日 07:46
• 549

## hdu 4052 Adding New Machine，set

hdu4052 Adding New Machine，set 比较老的题。给一个矩形和一些已经覆盖了的小矩形，问在剩余的空格上放一个长为m的条有多少种放法。 可以用线段树化为矩形面积并搞。这里...
• asdfgh0308
• 2014年10月15日 22:19
• 412

## HDU 4052 Adding New Machine （线段树）

• u014664226
• 2015年10月21日 12:02
• 242

## [线段树]HDU 4052 Adding New Machine

• zhaofukai
• 2012年08月21日 11:33
• 836

## UVA 1492 - Adding New Machine(线段树)

UVA 1492 - Adding New Machine 题目链接 题意：给定一些旧机器管辖范围，现在要放一台进新机器，新机器需要空间1*m,问有多少种放法 思路：转化为求面积并的...
• u011217342
• 2014年08月17日 14:25
• 947

## UVA1492 - Adding New Machine(扫描线)

UVA1492 - Adding New Machine(扫描线) 题目链接 题目大意：给你N∗M个格子，这些格子中某些格子是放了旧的机器，然后问现在要在这些格子放一台1∗M的新机器，问有...
• u012997373
• 2014年10月19日 20:57
• 547

举报原因： 您举报文章：hdu 4052 Adding New Machine 扫描线求矩形面积并 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)