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 }

http://acm.hdu.edu.cn/showproblem.php?pid=5091

posted on 2014-11-02 17:30  xiao_xin  阅读(283)  评论(0编辑  收藏  举报

导航