码迷,mamicode.com
首页 > 其他好文 > 详细

【POJ 1389】Area of Simple Polygons(线段树+扫描线,矩形并面积)

时间:2016-07-31 06:57:30      阅读:222      评论:0      收藏:0      [点我收藏+]

标签:

离散化后,[1,10]=[1,3]+[6,10]就丢了[4,5]这一段了。

因为更新[3,6]时,它只更新到[3,3],[6,6]。

要么在相差大于1的两点间加入一个值,要么就让左右端点为l,r的线段树节点表示到x[l]到x[r+1]的区间。

这样tree[l,r]=tree[l,m]+tree[m+1,r]=[x[l],x[m+1]]+[x[m+1],x[r+1]]

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define ll long long
#define N 2005
using namespace std;
struct P{ll s,e,h,f;}p[N];
struct Tree{ll sum,c;}t[N<<5];
int x[N],n,m,ans;
int cmp(const P &a,const P &b){
    return a.h<b.h;
}
void init(){
    n=m=ans=0;
    memset(p,0,sizeof p);
    memset(t,0,sizeof t);
    x[0]=-1;
}
void pushUp(ll rt,ll l,ll r){
    if(t[rt].c)t[rt].sum=x[r+1]-x[l];
    else if(l==r)t[rt].sum=0;
    else t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;
}
void update(ll s,ll e,ll rt,ll l,ll r,ll v){
    if(s<=l&&r<=e) t[rt].c+=v;
    else {
        if(l>e||r<s)return;
        ll m=l+r>>1;
        update(s,e,rt<<1,l,m,v);
        update(s,e,rt<<1|1,m+1,r,v);
    }
    pushUp(rt,l,r);
}
int main()
{
    int a,b,c,d;
    init();
    while(cin>>a>>b>>c>>d){
            if(a<0)break;
        while(a>=0){
            p[++n].s=a,p[n].e=c,p[n].h=b,p[n].f=1;x[n]=a;
            p[++n].s=a,p[n].e=c,p[n].h=d,p[n].f=-1;x[n]=c;
            cin>>a>>b>>c>>d;
        }
        sort(x+1,x+1+n);
        for(int i=1;i<=n;i++)
            if(x[i]!=x[i-1])x[++m]=x[i];

        sort(p+1,p+1+n,cmp);
        for(int i=1;i<n;i++){
            int l=lower_bound(x,x+m,p[i].s)-x;
            int r=lower_bound(x,x+m,p[i].e)-x-1;

            update(l,r,1,1,m,p[i].f);
            ans+=t[1].sum*(p[i+1].h-p[i].h);
        }
        cout<<ans<<endl;
        init();
    }
    return 0;
}

  

【POJ 1389】Area of Simple Polygons(线段树+扫描线,矩形并面积)

标签:

原文地址:http://www.cnblogs.com/flipped/p/5722284.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!