码迷,mamicode.com
首页 > 其他好文 > 详细

线段树+扫描线 HDOJ 5091 Beam Cannon

时间:2015-05-22 20:54:25      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:

 

题目传送门

  1 /*
  2     题意:给出若干个点的坐标,用一个矩形去覆盖,问最多能覆盖几个点
  3     线段树+扫描线:思路是先建一棵以[y, y + h]的树,左右儿子[x, x + w]
  4             以这棵树为范围,从左到右扫描,更新点数,x的+1, x+w的-1(超过矩形范围)
  5     ans = 每次更新时所覆盖点数的最大值
  6 */
  7 #include <cstdio>
  8 #include <algorithm>
  9 #include <iostream>
 10 #include <cstring>
 11 #include <cmath>
 12 #include <string>
 13 #include <vector>
 14 #include <queue>
 15 #include <map>
 16 #include <set>
 17 #include <ctime>
 18 #include <cstdlib>
 19 using namespace std;
 20 
 21 #define lson l, mid, rt << 1
 22 #define rson mid + 1, r, rt << 1 | 1
 23 typedef long long ll;
 24 
 25 const int MAXN = 1e4 + 10;        //n的范围
 26 const int MAXM = 4e4 + 10;        //x + 20000 范围
 27 const int INF = 0x3f3f3f3f;
 28 struct Node
 29 {
 30     int add, sum;
 31     int l, r;
 32 }node[MAXM << 2];
 33 struct P
 34 {
 35     int x, y, c;
 36 }p[MAXN * 2];
 37 
 38 void push_up(int rt)
 39 {
 40     node[rt].sum = max (node[rt<<1].sum, node[rt<<1|1].sum);
 41 }
 42 
 43 void push_down(int rt)
 44 {
 45     if (node[rt].add)
 46     {
 47         node[rt<<1].add += node[rt].add;
 48         node[rt<<1|1].add += node[rt].add;
 49         node[rt<<1].sum += node[rt].add;
 50         node[rt<<1|1].sum += node[rt].add;
 51         node[rt].add = 0;
 52     }
 53 }
 54 
 55 void build(int l, int r, int rt)
 56 {
 57     node[rt].add = 0;    node[rt].sum = 0;
 58     node[rt].l = l;    node[rt].r = r;
 59     if (l == r)    return ;
 60     int mid = (l + r) >> 1;
 61     build (lson);    build (rson);
 62 
 63     push_up (rt);
 64 }
 65 
 66 void updata(int ql, int qr, int c, int rt)
 67 {
 68     if (ql == node[rt].l && node[rt].r == qr)    {node[rt].sum += c;    node[rt].add += c;    return ;}
 69 
 70     push_down (rt);
 71 
 72     int mid = (node[rt].l + node[rt].r) >> 1;
 73     if (qr <= mid)    updata (ql, qr, c, rt << 1);
 74     else if (ql > mid)    updata (ql, qr, c, rt << 1 | 1);
 75     else
 76     {
 77         updata (ql, mid, c, rt << 1);
 78         updata (mid+1, qr, c, rt << 1 | 1);
 79     }
 80 
 81     push_up (rt);
 82 }
 83 
 84 bool cmp(P a, P b)
 85 {
 86     if (a.x == b.x)    return a.c > b.c;
 87     return a.x < b.x;
 88 }
 89 
 90 int main(void)        //HDOJ 5091 Beam Cannon
 91 {
 92     //freopen ("B.in", "r", stdin);
 93 
 94     int n, w, h;
 95     while (scanf ("%d", &n) == 1)
 96     {
 97         if (n < 0)    break;
 98         scanf ("%d%d", &w, &h);
 99         int cnt = 0;
100         for (int i=1; i<=n; ++i)
101         {
102             int x, y;
103             scanf ("%d%d", &x, &y);    x += 20000;    y += 20000;
104             p[++cnt].x = x;    p[cnt].y = y;
105             p[cnt].c = 1;
106             p[++cnt].x = x + w;    p[cnt].y = y;
107             p[cnt].c = -1;
108         }
109         sort (p+1, p+cnt+1, cmp);
110 
111         build (0, 40000, 1);
112 
113         int ans = 0;
114         for (int i=1; i<=cnt; ++i)
115         {
116             int y = p[i].y + h;    if (y > 40000)    y = 40000;
117             updata (p[i].y, y, p[i].c, 1);
118             ans = max (ans, node[1].sum);
119         }
120 
121         printf ("%d\n", ans);
122     }
123 
124     return 0;
125 }

 

线段树+扫描线 HDOJ 5091 Beam Cannon

标签:

原文地址:http://www.cnblogs.com/Running-Time/p/4523054.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!