zoukankan      html  css  js  c++  java
  • HDU 1542/POJ 1151 Atlantis (scaning line + segment tree)

    A template of discretization + scaning line + segment tree.
    It's easy to understand, but a little difficult for coding as it has a few details.

    #include"Head.cpp"
    
    const int N=207;
    
    double x[N<<1];
    
    struct Point{
    	double l,r,h;
    	int w;
    	bool operator< (const Point &b)const{
    		return h < b.h;
    	}
    }a[N<<2];
    
    struct SegmentTree{
    	int l,r,w;
    	double len;
    }t[N<<3];
    
    
    #define lson rt<<1, l, mid
    #define rson rt<<1|1, mid+1, r
    
    inline void Pushup(int rt){
    	if(t[rt].w != 0)
    		t[rt].len = x[t[rt].r+1] - x[t[rt].l];
    	else if(t[rt].l == t[rt].r)
    		t[rt].len = 0;
    	else // t[rt].w == 0
    		t[rt].len = t[rt<<1].len + t[rt<<1|1].len;
    }
    
    inline void Build(int rt,int l,int r){
    	t[rt] = (SegmentTree){l, r, 0, 0};
    	if(l == r) return;
    	int mid = (l>>1) + (r>>1) + (l&r&1);
    	Build(lson),Build(rson);
    }
    
    inline void Updata(int rt,int L,int R,int val){
    	if(t[rt].l >= L && t[rt].r <= R){
    		t[rt].w += val;
    		Pushup(rt);
    		return;
    	}
    	int mid = (t[rt].l>>1) + (t[rt].r>>1) +(t[rt].l&t[rt].r&1);
    	if(L <= mid) Updata(rt<<1, L, R, val);
    	if(R > mid) Updata(rt<<1|1, L, R, val);
    	Pushup(rt);
    }
    
    inline int FindPos(int l,int r,double val){
    	int mid;
    	while(l<=r){
    		mid = (l>>1) + (r>>1) + (l&r&1);
    		if(x[mid] > val)
    			r = mid - 1;
    		else if(x[mid] < val)
    			l = mid + 1;
    		else // x[mid] == val
    			break;
    	}
    	return mid;
    }
    
    int main(){
    	int task=0;
    	int n;
    	while(~scanf("%d",&n) && n!=0){
    		int cnt=0;
    		
    		R(i,1,n){
    			double x_1,x_2,y_1,y_2;
    			scanf("%lf%lf%lf%lf",&x_1,&y_1,&x_2,&y_2);
    			
    			// 1 -> floor, -1 -> ceiling
    			x[++cnt] = x_1;
    			a[cnt] = (Point){x_1, x_2, y_1, 1};
    			x[++cnt] = x_2;
    			a[cnt] = (Point){x_1, x_2, y_2, -1};
    		}
    		
    		sort(x+1, x+cnt+1);
    		sort(a+1, a+cnt+1);
    		Build(1, 1, cnt);
    		
    		double ans = 0;
    		R(i,1,cnt-1){
    			int l = FindPos(1, cnt, a[i].l),
    				r = FindPos(1, cnt, a[i].r) - 1;
    			Updata(1, l, r, a[i].w);
    			ans += t[1].len * (a[i+1].h - a[i].h);
    		}
    		
    		printf("Test case #%d
    Total explored area: %.2lf
    
    ", ++task, ans);
    	}
    	
    	return 0;
    }
    /*
    2
    10 10 20 20
    15 15 25 25.5
    0
    */
    
  • 相关阅读:
    PHP输出日志,json美化
    php获取项目路径
    16进制颜色,正则
    doctrine/instantiator
    cn.archive.ubuntu.com 慢的问题
    yzalis/identicon 像素头像
    Shell 判断进程是否存在
    shell 2>&1
    shell 判断是否继续
    shell
  • 原文地址:https://www.cnblogs.com/bingoyes/p/11144537.html
Copyright © 2011-2022 走看看