hdu5091(上海邀请赛B) 线段树+扫描线:求固定大小矩形内最多点个数
过几天再看看别人怎么做的。。
我是根据以前做的一道题目想到的思路,将某点变为2条线,该点是第一条线下面,线值为1,另一点在右边那条线下面,值为-1
然后区间修改求最大值。。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int tmp; 6 int maxv[400005],addv[400005]; 7 struct dian{ 8 int x,y1,y2,w; 9 }a[20005]; 10 int cmp(dian n1,dian n2) 11 { 12 if (n1.x<n2.x||(n1.x==n2.x&&n1.w>n2.w)) return 1; 13 return 0; 14 } 15 void update(int o,int l,int r,int y1,int y2,int v) 16 { 17 if (y1<=l&&y2>=r) addv[o]+=v; 18 else{ 19 int mid=l+(r-l)/2; 20 if (y1<=mid) update(o*2,l,mid,y1,y2,v); 21 if (y2>mid) update(o*2+1,mid+1,r,y1,y2,v); 22 } 23 if (r==l) maxv[o]=0; 24 else maxv[o]=max(maxv[o*2],maxv[o*2+1]); 25 maxv[o]+=addv[o]; 26 } 27 void query(int o,int l,int r,int y1,int y2,int add) 28 { 29 if (y1<=l&&y2>=r) tmp=max(tmp,maxv[o]+add); 30 else{ 31 int mid=l+(r-l)/2; 32 if (y1<=mid) query(o*2,l,mid,y1,y2,add+addv[o]); 33 if (y2>mid) query(o*2+1,mid+1,r,y1,y2,add+addv[o]); 34 } 35 } 36 int main() 37 { 38 int T,n,N,i,w,h,xx,yy,ans; 39 while (~scanf("%d",&n)&&n!=-1) 40 { 41 scanf("%d%d",&w,&h); N=0; 42 for (i=1;i<=n;i++) 43 { 44 scanf("%d%d",&xx,&yy); 45 a[2*i].x=xx; a[2*i].y1=yy+20001; a[2*i].y2=yy+h+20001; a[2*i].w=1; 46 a[2*i-1].x=xx+w; a[2*i-1].y1=yy+20001; a[2*i-1].y2=yy+h+20001; a[2*i-1].w=-1; 47 if (h+yy+20001>N) N=h+yy+20001; 48 } 49 sort(a+1,a+2*n+1,cmp); 50 memset(maxv,0,sizeof(maxv)); 51 memset(addv,0,sizeof(addv)); 52 ans=0; 53 for (i=1;i<=2*n;i++) 54 { 55 update(1,1,N,a[i].y1,a[i].y2,a[i].w); 56 tmp=0; 57 query(1,1,N,1,N,0); 58 ans=max(ans,tmp); 59 } 60 printf("%d\n",ans); 61 } 62 }