您的位置:首页 > 运维架构

HDU5091->线段树维护区间覆盖次数&&扫描线

2016-08-20 12:14 387 查看

HDU5091->线段树维护区间覆盖次数&&扫描线

题意:

一个平面上有一些点,给出这些点的坐标,求用一个宽为w高为h的格子最多能包含到多少个点

题解:

用一根平行于y轴的扫描线维护沿x轴方向的宽度,而沿y轴方向的点的个数的计算则可以等价为求一个区间内线段覆盖的最多次数。

由于已经给出高度h,所以每个点都可以看成是以这个点的y坐标为起始,长度为h的一条线段。

这里扫描线的运用,就是把一个点拆分成两个点,一个点的x坐标为其原有的x值,这个点为入点,记其flag为1,另一个点的x坐标为x+w,这个点为出点,记其flag为-1

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAX 20005
struct Node
{
int x , y1 , y2 , flag ;
}node[MAX];
struct Tree
{
int l , r , Ma , lazy ;
}tree[MAX << 2];
int y[MAX] ;
bool comp(const struct Node a , const struct Node b)
{
if(a.x == b.x) return a.flag > b.flag ;
return a.x < b.x ;
}
void build(int p , int l , int r)
{
tree[p].l = y[l] ;
tree[p].r = y[r] ;
tree[p].Ma = 0 ;
tree[p].lazy = 0 ;
if(l == r) return ;
int mid = (l + r) >> 1 ;
build(p << 1 , l , mid) ;
build(p << 1 | 1 , mid + 1 , r) ;
}
void Pushdown(int p)
{
if(tree[p].lazy != 0)
{
tree[p << 1].lazy += tree[p].lazy ;
tree[p << 1].Ma += tree[p].lazy ;
tree[p << 1 | 1].lazy += tree[p].lazy ;
tree[p << 1 | 1].Ma += tree[p].lazy ;
tree[p].lazy = 0 ;
}
}
void update(int p , int l , int r , int y1 , int y2 , int flag)
{
if(y1 <= tree[p].l &&y2 >= tree[p].r)
{
tree[p].Ma += flag ;
tree[p].lazy += flag ;
return ;
}
Pushdown(p) ;
int mid = (l + r) >> 1 ;
if(y2 <= y[mid]) update(p << 1 , l , mid , y1 , y2 , flag) ;
else if(y1 > y[mid]) update(p << 1 |1 , mid + 1 , r , y1 , y2 , flag) ;
else {
update(p <<1 , l , mid , y1 , y[mid] , flag) ;
update(p << 1 | 1 , mid + 1 , r , y[mid+ 1] , y2 , flag) ;
}
tree[p].Ma = max(tree[p<< 1].Ma , tree[p << 1 | 1].Ma) ;
}
int main()
{
int n , w , h ;
while(~scanf("%d" , &n) , n>0)
{
scanf("%d%d" , &w , &h) ;
for(int i = 0 ; i < n ; i ++)
{
int x0 , y0 ;
scanf("%d%d" , &x0 , &y0) ;
node[i].x = x0 ;
node[i].y1 = y0 ;
node[i].y2 = y0 + h ;
node[i].flag = 1 ;
y[i+1] = y0 ;
node[n+i].x = x0 +w ;
node[n+i].y1 = y0 ;
node[n+i].y2 = y0 + h ;
node[n+i].flag = -1 ;
y[n+i+1] = y0 + h ;
}
sort(node , node + 2*n , comp) ;
sort(y+1 , y + 1 + n*2) ;
int cnt = unique(y+1 , y + 2*n + 1) - y - 1 ;
build(1 , 1 , cnt) ;
int ans = 0 ;
for(int i = 0 ; i < 2*n ; i ++)
{
update(1 , 1 , cnt , node[i].y1 , node[i].y2 , node[i].flag) ;
ans = max(ans , tree[1].Ma) ;
}
printf("%d\n" , ans) ;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐