hdu 5091 Beam Cannon
题目大意:
有n个点(n<=10000),点的坐标绝对值不超过20000,然后问你用一个w*h(1<=w,h<=40000)的矩形,矩形的边平行于坐标轴,最多能盖住多少个点。
刘汝佳黑书上有原题
下面这份代码是加了离散化的,用垂直于x轴的直线去扫描,在y轴上建立线段树,所以对于每一个点(x,y),赋予权值1,,然后增加一个新的负点(x+w,y),赋予权值-1。当扫描线扫过每一个点,用该点的权值去区间更新线段树。维护每个区间的sum值,因为是区间更新,所以还要打个lazy标记。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<math.h> 4 #include<string.h> 5 #include<iostream> 6 #include<string> 7 #include<map> 8 #include<set> 9 #include<algorithm> 10 #include<queue> 11 #include<vector> 12 #define N 40000 13 using namespace std; 14 15 struct Node 16 { 17 int l,r,lazy; 18 int sum; 19 } node[N<<2]; 20 struct Line 21 { 22 int x,y1,y2,v; 23 Line(){} 24 Line(int a,int b,int c,int d) 25 { 26 x=a,y1=b,y2=c,v=d; 27 } 28 bool operator<(const Line&a)const 29 { 30 if(x==a.x) 31 return v>a.v; 32 return x<a.x; 33 } 34 } line[N]; 35 int lisan[N]; 36 int cnt=0; 37 void pushup(int rt) 38 { 39 node[rt].sum=max(node[rt<<1].sum,node[rt<<1|1].sum); 40 } 41 void pushdown(int rt) 42 { 43 if(node[rt].lazy) 44 { 45 node[rt<<1].lazy+=node[rt].lazy; 46 node[rt<<1|1].lazy+=node[rt].lazy; 47 node[rt<<1].sum+=node[rt].lazy; 48 node[rt<<1|1].sum+=node[rt].lazy; 49 node[rt].lazy=0; 50 } 51 } 52 void build(int rt,int l,int r) 53 { 54 node[rt].sum=0,node[rt].lazy=0; 55 node[rt].l=l,node[rt].r=r; 56 if(l==r) 57 return; 58 int mid=l+r>>1; 59 build(rt<<1,l,mid); 60 build(rt<<1|1,mid+1,r); 61 pushup(rt); 62 } 63 void update(int rt,int l,int r,int v) 64 { 65 if(l<=node[rt].l&&node[rt].r<=r) 66 { 67 node[rt].lazy+=v; 68 node[rt].sum+=v; 69 return; 70 } 71 pushdown(rt); 72 int mid=node[rt].l+node[rt].r>>1; 73 if(l<=mid) 74 update(rt<<1,l,r,v); 75 if(r>mid) 76 update(rt<<1|1,l,r,v); 77 pushup(rt); 78 } 79 int query(int rt,int l,int r) 80 { 81 if(l<=node[rt].l&&node[rt].r<=r) 82 { 83 return node[rt].sum; 84 } 85 pushdown(rt); 86 int mid=node[rt].l+node[rt].r>>1,ans=0; 87 if(l<=mid) 88 ans+=query(rt<<1,l,r); 89 if(r>mid) 90 ans+=query(rt<<1|1,l,r); 91 return ans; 92 } 93 int main() 94 { 95 int n,w,h; 96 while(scanf("%d",&n)) 97 { 98 cnt=0; 99 if(n<0) 100 break; 101 scanf("%d%d",&w,&h); 102 for(int i=0;i<n;++i) 103 { 104 int x,y; 105 scanf("%d%d",&x,&y); 106 x+=20001; 107 y+=20001; 108 lisan[cnt]=y; 109 line[cnt++]=Line(x,y,y+h,1); 110 lisan[cnt]=y+h; 111 line[cnt++]=Line(x+w,y,y+h,-1); 112 } 113 sort(line,line+cnt); 114 sort(lisan,lisan+cnt); 115 int num=unique(lisan,lisan+cnt)-lisan; 116 build(1,0,num-1); 117 int ans=0; 118 for(int i=0;i<cnt;++i) 119 { 120 int l=lower_bound(lisan,lisan+num,line[i].y1)-lisan; 121 int r=lower_bound(lisan,lisan+num,line[i].y2)-lisan; 122 update(1,l,r,line[i].v); 123 ans=max(ans,node[1].sum); 124 } 125 printf("%d\n",ans); 126 } 127 128 }