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
- HDU5091->线段树维护区间覆盖次数&&扫描线
- hdu5091 线段树扫描线
- hdu5091(扫描线+线段树)
- HDU5091 Beam Cannon(线段树扫描线)
- 【HDU5091】Beam Cannon,扫描线+线段树
- hdu5091-Beam Cannon 线段树+扫描线 求矩形内最多能包含多少个点
- 线段树--区间覆盖
- POJ 3667 Hotel(线段树:区间覆盖,维护最大连续子区间)
- HDU 3577 Fast Arrangement(线段树功能:区间更新,查询区间的最大覆盖次数)
- 线段树区间维护upcoj
- 线段树区间维护hdu3308
- 线段树区间维护hdu3397
- 线段树区间维护cf46D
- POJ3468 线段树区间维护
- hdoj 3397 Sequence operation 【线段树区间覆盖 + 异或 + 合并】【维护延迟标记的顺序】
- POJ2528 线段树区间覆盖
- hdu 3577 线段树,成段更新 好题 查询区间的最大覆盖次数
- 线段树 区间覆盖 区间增加
- maven入门基础知识
- Linux服务器使用情况简单介绍
- Top K Frequent Elements
- 子类构造和析构被执行时是否调用父类以及调用顺序
- 化学盐
- HDU5091->线段树维护区间覆盖次数&&扫描线
- 时滞微分方程求解之三ddesd--变时滞
- kxmovie源码详解
- 0-1背包问题
- iOS 杂烩
- 《C++ Primer》读书笔记-IO流操作
- 在模拟器上安装APK文件的方法
- 2016/08/20 集合框架
- Jquery李炎恢——33,34插件