Picture hdu 1828 扫描线

来源:互联网 发布:复旦大学有网络教育 编辑:程序博客网 时间:2024/06/07 02:08

http://acm.hdu.edu.cn/showproblem.php?pid=1828

扫描线第二题,1A

思路:按照x轴和y轴各扫一次,也就是分两次计算,一次计算与x轴平行的周长 ,另一次与y轴,他们的和就是总周长.

每条边分左右两种边插进去线段树,线段树的cnt维护这个线段[l,r]已经被覆盖了多少次

1.如果左边线段覆盖 那么这一段上面全部+1;

2.如果右边 -1;

这样我们就知道在任意的区间有没有被覆盖过,被覆盖过了多少次;

1.当左边的边覆盖cnt为0的区域的时候,周长加上这段的没有被覆盖的长度

2.当右边的边减去覆盖,这时线段的cnt为1,减去后就变成0了,也就是出去的那条边的周长也要计算进去,所以答案也加上这段的长度;

#include <iostream>#include <cstdio>#include <vector>#include <cstring>#include <algorithm>#define lc idx<<1#define rc idx<<1|1#define mid ((l+r)>>1)#define lson lc,l,mid#define rson rc,mid,r#define whole idx,l,rusing namespace std;const int MAXN=10000*2+2;struct Scanline{    int x,yu,yd,v;    Scanline(){}    Scanline(int xx,int yy,int yyyy,int vv) :x(xx),yu(yy),yd(yyyy),v(vv) {}    bool operator <(const Scanline &a) const    {        return x<a.x;    }};vector<Scanline> a,b;class SGtree{private:        int cnt[MAXN<<2];public:    void build(int idx,int l,int r)    {        cnt[idx]=0;        if(l+1==r) return ;        build(lson);        build(rson);    }    void PushDown(int idx,int l,int r)    {        if(cnt[idx]!=-1)        {            cnt[lc]=cnt[rc]=cnt[idx];            cnt[idx]=-1;        }    }    int update(int idx,int l,int r,int x,int y,int v)    {        int ret=0;        if(x<=l && r<=y && cnt[idx]!=-1)        {            cnt[idx]+=v;            if(cnt[idx]==0 || (v==1 && cnt[idx]==1))                return r-l;        }        else        {            PushDown(whole);            if(x<mid) ret+=update(lson,x,y,v);            if(y>mid) ret+=update(rson,x,y,v);        }        return ret;    }};int n;SGtree tree;int sumup(vector<Scanline> &a){    sort(a.begin(),a.end());    int ret=0;    tree.build(1,1,MAXN);    for(int i=0;i<a.size();i++)    {        Scanline x=a[i];        int p=tree.update(1,1,MAXN,x.yd,x.yu,x.v);        ret+=p;    }    return ret;}int main(){    while(~scanf("%d",&n))    {        a.clear();        b.clear();        int x1,y1,x2,y2;        for(int i=0;i<n;i++)        {            scanf("%d %d %d %d",&x1,&y1,&x2,&y2);            x1+=10000;            y1+=10000;            x2+=10000;            y2+=10000;            a.push_back(Scanline(x1,y2,y1,1));            a.push_back(Scanline(x2,y2,y1,-1));            b.push_back(Scanline(y1,x2,x1,1));            b.push_back(Scanline(y2,x2,x1,-1));        }        int ans=0;        ans+=sumup(a);        ans+=sumup(b);        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击