zoukankan      html  css  js  c++  java
  • HDU-1828 Picture(扫描线)

    题目大意:给若干个矩形,求轮廓边长。

    题目分析:与求面积类似。按从下往上扫描,仍然是底边添加,上边删除。但要同时维护竖边的数目,每次扫描对答案的贡献为扫描线上总覆盖长度的变化量加上竖边的增量。总覆盖长度的变化为正说明下轮廓增加,为负以为着碰到了上轮廓增加。

    代码如下:

    # include<bits/stdc++.h>
    using namespace std;
    # define mid (l+(r-l)/2)
    # define LL long long
    
    const int N=5000;
    
    struct Segment
    {
    	int x1,x2,y;
    	int d;
    };
    struct Node
    {
    	int cnt;	///覆盖的竖线数目
    	int len;	///被覆盖总长度
    	int time;	///被覆盖覆盖的次数
    	bool cl,cr;	///左右端点是否被覆盖
    };
    Segment seg[N<<1];
    Node nde[(N<<4)+5];
    
    bool comp(Segment &s1,Segment &s2)
    {
    	return s1.y<s2.y;
    }
    
    void build(int rt,int l,int r)
    {
    	nde[rt].cnt=0;
        nde[rt].len=0;
    	nde[rt].time=0;
    	nde[rt].cl=nde[rt].cr=false;
    	if(l==r) return ;
    	build(rt<<1,l,mid);
    	build(rt<<1|1,mid+1,r);
    }
    
    void pushUp(int rt,int l,int r)
    {
    	if(nde[rt].time>0){
    		nde[rt].cl=nde[rt].cr=true;
    		nde[rt].cnt=2;
    		nde[rt].len=r-l+1;
    	}else if(l==r){
    		nde[rt].cl=nde[rt].cr=false;
    		nde[rt].cnt=0;
    		nde[rt].len=0;
    	}else{
    		nde[rt].cl=nde[rt<<1].cl;
    		nde[rt].cr=nde[rt<<1|1].cr;
    		nde[rt].len=nde[rt<<1].len+nde[rt<<1|1].len;
    		nde[rt].cnt=nde[rt<<1].cnt+nde[rt<<1|1].cnt;
    		if(nde[rt<<1].cr&&nde[rt<<1|1].cl)
    			nde[rt].cnt-=2;
    	}
    }
    
    void update(int rt,int l,int r,int L,int R,int d)
    {
    	if(L<=l&&r<=R){
    		nde[rt].time+=d;
    		pushUp(rt,l,r);
    	}else{
    		if(L<=mid) update(rt<<1,l,mid,L,R,d);
    		if(R>mid) update(rt<<1|1,mid+1,r,L,R,d);
    		pushUp(rt,l,r);
    	}
    }
    
    int main()
    {
    	int n;
    	while(~scanf("%d",&n))
    	{
    		int L=10000,R=-10000;
    		int x1,y1,x2,y2;
    		for(int i=0;i<n;++i){
    			scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    			seg[i<<1].x1=seg[i<<1|1].x1=x1,seg[i<<1].y=y1;
    			seg[i<<1].x2=seg[i<<1|1].x2=x2,seg[i<<1|1].y=y2;
    			seg[i<<1].d=1;
    			seg[i<<1|1].d=-1;
    			L=min(x1,L);
    			R=max(x2,R);
    		}
    		n<<=1;
    		build(1,L,R-1);
    		sort(seg,seg+n,comp);
    		int ans=0;
    		int last=0;
    		seg[n].y=seg[n-1].y;
    		for(int i=0;i<n;++i){
    			update(1,L,R-1,seg[i].x1,seg[i].x2-1,seg[i].d);
    			ans+=nde[1].cnt*(seg[i+1].y-seg[i].y);
    			ans+=abs(nde[1].len-last);
    			last=nde[1].len;
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    2009年信息技术十大趋势
    转:ASP.NET MVC 第五个预览版和表单提交场景
    终于在博客园开通了
    与虚拟机Oracle连接出现ora12154问题的解决
    Frame框架页面加载中进度条的实现
    WordPress安装部署
    Xmarks不会关闭了,太好了!
    抠出淘宝的菜单树
    asp.net实现类似MaskTextBox功能
    win2003 64位系统下ODBC连接使用
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5748485.html
Copyright © 2011-2022 走看看