HDU 5091 --- Beam Cannon (line segment tree + scanning line), hdu5091 --- beam

Question Link

Http://acm.hdu.edu.cn/showproblem.php? Pid = 1, 5091

**Problem Description**Recently, the gamma galaxies broke out Star Wars. each planet is warring for resources. in the Star Wars, Planet X is under attack by other planets. now, a large wave of enemy spaceships is approaching. there is a very large Beam Cannon on the Planet X, and it is very powerful, which can destroy all the spaceships in its attack range in a second. however, it takes a long time to fill the energy of the Beam Cannon after each shot. so, you shocould make sure each shot can destroy the enemy spaceships as stored as possible.

To simplify the problem, the Beam Cannon can shot at any area in the space, and the attack area is rectangular. the rectangle parallels to the coordinate axes and cannot rotate. it can only move horizontally or vertically. the enemy spaceship in the space can be considered as a point projected to the attack plane. if the point is in the rectangular attack area of the Beam Cannon (including border), the spaceship will be destroyed.

**Input**Input contains multiple test cases. each test case contains three integers N (1 <= N <= 10000, the number of enemy spaceships), W (1 <= W <= 40000, the width of the Beam Cannon's attack area), H (1 <= H <= 40000, the height of the Beam Cannon's attack area) in the first line, and then N lines follow. each line contains two integers x, y (-20000 <= x, y <= 20000, the coordinates of an enemy spaceship ).

A test case starting with a negative integer terminates the input and this test case shocould not to be processed.

**Output**Output the maximum number of enemy spaceships the Beam Cannon can destroy in a single shot for each case.

**Sample Input**2 3 40 11 03 1-1 00 11 0-1

**Sample Output**22

**Source**2014 Shanghai national invitational competition-reproduction of the questions (thanks to Shanghai University for providing the questions)

**Recommend**Hujie | We have carefully selected several similar problems for you: 5932 5931 5930 5929 5928 question: there are n points on the plane, and now there is a rectangle parallel to the coordinate axis, if the width is w and h, it can be moved up or down, but cannot be rotated. How many points can this rectangle enclose at most? Train of Thought: sort the input n points in ascending order of X-axis. For convenience of calculation, you can record a mark point (marked) for each point during input ), if the input vertex is node [I]. x = x node [I]. y = y node [I]. v = 1 then add a flag node [I + 1]. x = x + w node [I + 1]. y = y node [I + 1]. v =-1: When calculating the 2 * n vertices after sorting, only the vertices with a length of w are calculated, the point out of the w length range is calculated in node [I + 1]. v =-1. Now, all the points to be considered are within the range of w. Now you only need to consider the height. You can use the line segment tree to calculate the node [I] for the current node [I]. y ~ If node [I]. y + h is added with node [I]. v, the maximum value obtained by the line segment tree is the value of the current interval point. Why? Because all the points to be considered are in the w-length range, you only need to consider the y value. Therefore, you can convert these points to a straight line, and find that the line segment with the length of h can cover the most points, considering the position of the upper endpoint of a line segment, the contribution of a point to the upper endpoint is y ~ In the y + h range, the endpoint value is the overwrite value of the line segment. The Code is as follows:

#include <algorithm>#include <iostream>#include <cstring>#include <cstdio>#include <cmath>using namespace std;typedef long long LL;const int N=1e4+5;int n,w,h;struct Node{ int x,y,v;}node[2*N];struct TNode{ int f; int m;}tr[16*N];bool cmp(const Node s1,const Node s2){ if(s1.x==s2.x) return s1.v>s2.v; return s1.x<s2.x;}void build(int l,int r,int i){ tr[i].f=0; tr[i].m=0; if(l==r) return ; int mid=(l+r)>>1; build(l,mid,i<<1); build(mid+1,r,i<<1|1);}void pushdown(int i){ tr[i<<1].f+=tr[i].f; tr[i<<1|1].f+=tr[i].f; tr[i<<1].m+=tr[i].f; tr[i<<1|1].m+=tr[i].f; tr[i].f=0;}void update(int l,int r,int i,int t){ if(l>=node[t].y&&r<=node[t].y+h) { tr[i].f+=node[t].v; tr[i].m+=node[t].v; return ; } if(tr[i].f!=0) pushdown(i); int mid=(l+r)>>1; if(node[t].y<=mid) update(l,mid,i<<1,t); if(node[t].y+h>mid) update(mid+1,r,(i<<1|1),t); tr[i].m=max(tr[i<<1].m,tr[i<<1|1].m);}int main(){ while(scanf("%d",&n)&&n>0) { scanf("%d%d",&w,&h); for(int i=1;i<=n;i++) { int x,y; scanf("%d%d",&x,&y); node[2*i-1].x=x; node[2*i-1].y=y+2*N; node[2*i-1].v=1; node[2*i].x=x+w; node[2*i].y=y+2*N; node[2*i].v=-1; } sort(node+1,node+2*n+1,cmp); build(1,4*N,1); int sum=0; for(int i=1;i<=2*n;i++) { update(1,4*N,1,i); sum=max(sum,tr[1].m); } printf("%d\n",sum); } return 0;}