zoukankan      html  css  js  c++  java
  • poj 1151 Atlantis 扫描线

    题目:poj1151

    建议先参考参考别的扫描线文档。

    考虑这样一些矩形:

    pic1

    拿一根扫描线从左往右扫,扫描线被矩形覆盖的长度会变化当扫过矩形的左右边界时。

    我们就剥离出来左右边界。我们把所有的 (y) 值都保存下来离散化。

    我们拿线段树维护扫描线。线段树结点应保存从第几个 (y) 开始到第几个 (y) 结束,有多少个区间是有覆盖的。因此,维护 (l) 个到 (r) 个的结点,它的子结点是 (l sim mid)(mid sim r)。这是与普通线段树的差别之一。

    pic2

    应该打上懒标记的,只不过我没搞

    #include <algorithm>
    #include <iostream>
    #include <cstdio>
    using namespace std;
    int n, casecnt, cnt, m;
    double ans, uu, vv, ww, zz, yy[205];
    struct Line{
    	double xx, yu, yv;
    	int fla;
    }li[205];
    struct Node{
    	int cov;
    	double val;
    	void clr(){
    		cov = val = 0;
    	}
    }nd[805];
    bool cmp(Line x, Line y){
    	return x.xx<y.xx;
    }
    void build(int o, int l, int r){
    	int mid=(l+r)>>1;
    	int lson=o<<1;
    	int rson=lson|1;
    	if(l+1==r)	nd[o].clr();
    	else{
    		if(l<=mid)	build(lson, l, mid);
    		if(mid<=r)	build(rson, mid, r);
    	}
    }
    void qwq(int o, int l, int r, const Line &x){
    	nd[o].cov += x.fla;
    	if(!nd[o].cov)	nd[o].val = 0.0;
    	else	nd[o].val = yy[r] - yy[l];
    }
    void update(int o, int l, int r, const Line &x){
    	if(l+1==r)	qwq(o, l, r, x);
    	else{
    		int mid=(l+r)>>1;
    		int lson=o<<1;
    		int rson=lson|1;
    		if(yy[mid]>x.yu)	update(lson, l, mid, x);
    		if(yy[mid]<x.yv)	update(rson, mid, r, x);
    		nd[o].val = nd[lson].val + nd[rson].val;
    	}
    }
    int main(){
    	while(scanf("%d", &n)!=EOF){
    		if(!n)	break;
    		casecnt++;
    		ans = 0.0;
    		cnt = m = 0;
    		for(int i=1; i<=n; i++){
    			scanf("%lf %lf %lf %lf", &uu, &vv, &ww, &zz);
    			yy[++cnt] = vv;
    			li[cnt].xx = uu; li[cnt].yu = vv; li[cnt].yv = zz; li[cnt].fla = 1;
    			yy[++cnt] = zz;
    			li[cnt].xx = ww; li[cnt].yu = vv; li[cnt].yv = zz; li[cnt].fla = -1;
    		}
    		sort(yy+1, yy+1+cnt);
    		m = unique(yy+1, yy+1+cnt) - yy - 1;
    		sort(li+1, li+1+cnt, cmp);
    		build(1, 1, m);
    		for(int i=1; i<=cnt; i++){
    			ans += nd[1].val * (li[i].xx - li[i-1].xx);
    			update(1, 1, m, li[i]);
    		}
    		printf("Test case #%d
    Total explored area: %.2f
    
    ", casecnt, ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    PHP 批量生成静态文件目录代码
    PHP 导出Excel 文档
    Samba Server 配置
    PHP curl超时问题
    php ci 2.0框架 ORM
    YII 的基本CURL操作
    PHP 操作socket 实现简易聊天室
    PHP simplexml_load_string 过滤<![CDATA[XXXX]]>
    PHP 获取当天 凌晨 时间戳常用代码
    2019年值得你使用的20大开发工具
  • 原文地址:https://www.cnblogs.com/poorpool/p/8459658.html
Copyright © 2011-2022 走看看