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

来源:互联网 发布:网络推广代理公司 编辑:程序博客网 时间:2024/04/30 23:03

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 20005struct 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;}
0 0
原创粉丝点击