HDU - 1542 (扫描线+线段树优化)

有些需要说明的地方:


以前写线段树时线段树的每个叶节点为一个数字,代表一个区域 (7 ,代表第七个单位长度区域);

本题不同在于,最小单位区域必须有两点代表(2-3 代表从2到3 的一个区域)


上篇扫描线算法复杂度为o(n^2) 本题用离散化法加线段树优化为nlog(n);


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

#define lson l,m,rt<<1
#define rson m,r,rt<<1|1
#define INF 1000000100

const int maxn = 210;

double ty[maxn];
int kk;
int find(double value){
int p=lower_bound(ty+1,ty+kk,value) - ty;
//cout<<p<<"-->"<<ty[p]<<endl;
return p;
}

int flag;
struct Line{
double x,y1,y2;
int side;
Line(){}
void get(double xx=0,double yy1=0,double yy2=0,int sidee=0){
        x=xx; y1=yy1; y2=yy2; side=sidee;
    }
bool operator<(const Line& rhs)const{
return x < rhs.x;
}
}line[maxn];
struct Warm_house{
double x;
double y1,y2;
int flag;
 Warm_house(){}
void get(double yy1=0,double yy2=0,int f=0){
    y1=yy1; y2=yy2; flag=f;
}
}warm[maxn<<2];
void build(int l,int r,int rt){
  //  cout<<rt<<endl;
warm[rt].flag=0;
warm[rt].y1=ty[l];
warm[rt].y2=ty[r];
if(l==r-1) return ;
int m=(l+r)>>1;
build(lson);
build(rson);
}
double ans;
int ql,qr,fff;
double x;
void update(int l,int r,int rt){

if(l==r-1){
    //if(ql<=l&&r<=qr){
    //cout<<l<<" "<<r<<endl;
    if(warm[rt].flag>0){
        ans+=(x-warm[rt].x)*(ty[r]-ty[l]);
        warm[rt].x=x;
        warm[rt].flag+=fff;
    }
    else {
        warm[rt].x=x;
        warm[rt].flag+=fff;
    }
    //}
    return ;
}
int m=(r+l)>>1;
if(ql<m) update(lson);
if(qr>m) update(rson);
}
int main()
{
   int n,kase=1;
   double x1,y1,x2,y2;
   while(scanf("%d",&n)==1&&n){
      int id=1;
      for(int i=1;i<=n;i++){
        scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
        ty[id]=y1;
        line[id].get(x1,y1,y2,1);
        id++;
        ty[id]=y2;
        line[id].get(x2,y1,y2,-1);
        id++;
      }

      sort(ty+1,ty+id);
      sort(line+1,line+id);

      kk = unique(ty+1,ty+id)-(ty+1);

      build(1,kk,1);
      ans=0;
      for(int i=1;i<id;i++){
           double gy1=line[i].y1,gy2=line[i].y2;
           x=line[i].x;
           fff=line[i].side;
           ql=find(gy1);
           qr=find(gy2);
           update(1,kk,1);
      }

      printf("Test case #%d\nTotal explored area: ",kase++);
      printf("%.2lf\n\n",ans);
   }
return 0;
}


你可能感兴趣的:(Algorithm,C++,算法,HDU)