复习了一下线段树,才发现线段树还是做的太少了,好多都忘了
线段树主要有以下功能:RMQ,区间总和查询,单点更新,区间更新
都忘了区间更新时要延迟更新了,这里一开始WA了。
再说说这题的思路:
把每个点作为矩形的左下角,画出所有矩形,以被矩形覆盖次数最多的区域中的任一点作为矩形的右上角,即为我们要求的矩形。
也就是说,我们要求的是被矩形覆盖次数最多的次数,这样用扫描线就可以解决,但直接扫描过去的话要n^2复杂度,会超时,于是使用线段树
每扫描到一条边,即相当于对该点覆盖的y轴区间内所有值进行了一次更新,即区间更新,这样维护一个最大值就好了
#include<stdio.h> #include<algorithm> using namespace std; #define N 20005 struct Line{ int x,y1,y2,flag; }s[N]; int y[N]; int max(int a,int b){ return a>b?a:b; } struct Node{ int l,r,ma,add; }node[N*4]; int cmp(Line a,Line b){ if(a.x==b.x) return a.flag>b.flag; return a.x<b.x; } void Build(int cur,int l,int r){//[l,r) node[cur].l=l; node[cur].r=r; node[cur].ma=0; node[cur].add=0; if(l==r){//当前结点为l return; } int mid=(l+r)>>1; Build(cur*2,l,mid); Build(cur*2+1,mid+1,r); } void push_down(int cur){ node[cur*2].add+=node[cur].add;//留给孙子结点的值 node[cur*2+1].add+=node[cur].add; node[cur*2].ma+=node[cur].add; node[cur*2+1].ma+=node[cur].add; node[cur].add=0; } void update(int cur,Line p){//要注意延迟更新,如果每一次都更新到叶结点的话复杂度就变成了n^2, if(y[node[cur].l]>p.y2||y[node[cur].r]<p.y1) return; if(y[node[cur].l]>=p.y1&&y[node[cur].r]<=p.y2){ node[cur].ma+=p.flag; node[cur].add+=p.flag;//当前结点的add是需要给子结点加上的 return; } /*if(node[cur].l==node[cur].r) { return;//退化为某个点了,跳出 }*///这一句有前面的条件,不用写了,要么完全包含,要么完全不包含,其他的都要继续往下找 push_down(cur); int mid=(node[cur].l+node[cur].r)>>1; update(cur*2,p); update(cur*2+1,p); node[cur].ma=max(node[cur*2+1].ma,node[cur*2].ma);//能执行到这一步,说明子结点的值已经更新了 } int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int n,w,h; while(scanf("%d%d%d",&n,&w,&h)){ if(n<0) break; int tmp1,tmp2; int cnt=1; int i; for(i=0;i<n;i++) { scanf("%d%d",&tmp1,&tmp2); s[cnt].x=tmp1; s[cnt].y1=tmp2; s[cnt].y2=tmp2+h; y[cnt]=tmp2; s[cnt++].flag=1; s[cnt].x=tmp1+w; s[cnt].y1=tmp2; s[cnt].y2=tmp2+h; y[cnt]=tmp2+h; s[cnt++].flag=-1; } sort(y+1,y+cnt); sort(s+1,s+cnt,cmp); int ycnt=unique(y+1,y+cnt)-y; Build(1,1,ycnt-1); int ans=0; for(i=1;i<cnt;i++){ update(1,s[i]); ans=max(ans,node[1].ma); } printf("%d\n",ans); } }
原文地址:http://blog.csdn.net/lj94093/article/details/45442643