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 }

 

posted on 2015-04-30 23:34  tsw123  阅读(285)  评论(0编辑  收藏  举报

导航