POJ 1151 Atlantis(スキャンライン法、ラインセグメントツリー、離散化)

POJ 1151 Atlantis(スキャンライン法、ラインセグメントツリー、離散化)

ブルーブックラインセグメントツリーの演習POJ 1151 Atlantis
質問の意味:n個の長方形の左下と右上に2つの座標点(x、y)(x、y)がある場合x y 、それらの面積と(総面積)
データ範囲を検索n:100、x / y:1 e 5 n:100、x / y:1e51 0 0 x / y 1 e 5

アイデア:私は今とても眠いので、明日書きます^^

LL n;
struct SegmentTree{
    
    
	int l,r,add;
	double dat;
	#define l(x) tree[x].l
    #define r(x) tree[x].r
    #define dat(x) tree[x].dat
    #define add(x) tree[x].add
}tree[maxn*8];
struct node{
    
    
    double x,y,z;
    int c,zz,yy;
    bool operator <(const node aa)const{
    
    
        return x<aa.x;
    }
}a[maxn*2];
double  b[maxn*2];

void build(int p,int l,int r){
    
    
	l(p)=l,r(p)=r;
	dat(p)=0;add(p)=0;
	if(l==r) {
    
    return;}
	int mid=(l+r)/2;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
}

void lazy(int p){
    
    
	if(add(p)){
    
    
		dat(p*2)+=add(p);
		dat(p*2+1)+=add(p);
		add(p*2)+=add(p);
		add(p*2+1)+=add(p);
		add(p)=0;
	}
}

void change(int p,int l,int r,double z){
    
    
	if(l<=l(p)&&r>=r(p)){
    
    dat(p)=((add(p)+=z)?b[r(p)+1]-b[l(p)]:0);}
	if(l(p)==r(p)){
    
    return;}
	int mid=(l(p)+r(p))/2;
	if(l<=mid) change(p*2,l,r,z);
    if(r>mid) change(p*2+1,l,r,z);
	if(add(p))dat(p)=b[r(p)+1]-b[l(p)];
	else dat(p)=dat(2*p)+dat(2*p+1);
}

LL ask(int p,int l,int r)
{
    
    
	if(l<=l(p)&&r>=r(p)) return dat(p);
	lazy(p);
    int mid=(l(p)+r(p))/2;
	LL ans=0;
    if(l<=mid) ans+=ask(p*2,l,r);
    if(r>mid) ans+=ask(p*2+1,l,r);
    return ans;
}

int main(){
    
    
    LL co,sum=0;
    double ans;
    while(scanf("%lld",&n)!=EOF&&n){
    
    
        ans=0;
        for(int i=1;i<=n;i++){
    
    
            scanf("%lf%lf%lf%lf",&a[2*i-1].x,&a[2*i-1].y,&a[i*2].x,&a[2*i].z);
            b[i*2-1]=a[2*i].y=a[2*i-1].y;
            b[2*i]=a[2*i-1].z=a[2*i].z;
            a[2*i].c=-1;
            a[2*i-1].c=1;
        }
        n*=2;
        sort(b+1,b+1+n);
        co=unique(b+1,b+1+n)-b-1;
        for(int i=1;i<=n;i++){
    
    
            a[i].yy=lower_bound(b+1,b+co+1,a[i].y)-b;
            a[i].zz=lower_bound(b+1,b+1+co,a[i].z)-b;
        }
        sort(a+1,a+1+n);
        build(1,1,co-1);
        for(int i=1;i<=n;i++){
    
    
            change(1,a[i].yy,a[i].zz-1,a[i].c);
            ans+=(a[i+1].x-a[i].x)*tree[1].dat;
        }
        printf("Test case #%lld\nTotal explored area: %.2f\n\n",++sum,ans);
    }
}

おすすめ

転載: blog.csdn.net/weixin_44986601/article/details/105807034