现在的位置: 首页 > 综合 > 正文

HDU – 5091(扫描线 + 线段树优化)

2019年04月04日 ⁄ 综合 ⁄ 共 1580字 ⁄ 字号 评论关闭

做法,

将读入的每个点(x,y)看做一个以该点为左上角宽W高H的矩形, 然后将矩形看做两条平行y轴(起点y-h,终点y)线,横坐标分别为 x , x+W; 

然后可用经典的扫描线算法求解该题,即找出所有矩形重叠的最多次数,即所求值

证明 :

都在一个矩形内的点必定他们的上述规定的矩形都两两相交,而矩形两两相交必然有共同的交点是的所有矩形都相交于此;

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cctype>
#include <set>
using namespace std;

#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1|1)

const int    N = 81500;
const int maxn = 10010;
const int yadd = 61000;

int x[maxn],y[maxn],n,W,H;
struct segment{
int x,y1,y2,flag;
segment(int x,int y1,int y2,int f):x(x),y1(y1),y2(y2),flag(f){}
bool operator < (const segment& rhs) const {
return x < rhs.x || x == rhs.x  && flag > rhs.flag;
}
};
vector<segment> ans;

int MAX[N<<2],col[N<<2];
void build(int l,int r,int rt){
MAX[rt]=col[rt]=0;
if(l==r) return;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void pushup(int rt){
MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
}
void pushdown(int rt){
if(col[rt]!=0){
     col[rt<<1]+=col[rt];
     col[rt<<1|1]+=col[rt];
     MAX[rt<<1]+=col[rt];
     MAX[rt<<1|1]+=col[rt];
     col[rt]=0;
}
}
int Ans,ql,qr,fff;
void update(int l,int r,int rt){
if(ql<=l&&r<=qr){
      MAX[rt]+=fff;
      col[rt]+=fff;
      Ans= max(MAX[rt],Ans);
      return ;
}
pushdown(rt);
int m=(l+r)>>1;
if(ql<=m) update(lson);
if(qr> m) update(rson);
pushup(rt);
}
int MAXS = 81250;
int main()
{
   while(scanf("%d",&n)==1 && n!=-1){
        scanf("%d %d",&W,&H);
        int xx,yy;
       ans.clear();
       for(int i=1;i<=n;i++){
        scanf("%d %d",&xx,&yy);
        x[i]=xx;
        y[i]=yy+yadd;
        ans.push_back(segment(x[i],y[i],y[i]-H,1));
        ans.push_back(segment(x[i]+W,y[i],y[i]-H,-1));
       }
       sort(ans.begin(),ans.end());

       build(1,MAXS,1);
       int res=0;
       for(int i=0;i<ans.size();i++){
           segment& temp = ans[i];
           Ans=0;
           ql=temp.y2,qr=temp.y1;
           fff=temp.flag;
           update(1,MAXS,1);
           res=max(res,Ans);
       }
       printf("%d\n",res);
   }
   return 0;
}

抱歉!评论已关闭.