Atlantis hdu 1542 线段树 扫面线 区间合并

来源:互联网 发布:黑马程序员基础测试题 编辑:程序博客网 时间:2024/06/08 09:55

扫描线第一题,第一次交上去居然PE了,好吧,有傻逼了,少加个了个回车.

注意点:

1. 区间分段的时候要分成 [l,mid] 和[mid,r]不是平常一样的[l,mid]和[mid+1,r](因为我们要算的一段线段的长度,也就是说得连续,比如我们要算这一段[1,10],应该把他分成[1,5][5,10],不能[1,5][6,10]);

2.由于上面的mid和平时的线段树不同,所以判断退出的时候是(l+1==r)才退出,因为我们表示的是一段线段,每个值是一个点,如果l等于r的话,就是一个点了,也没意义了.

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <vector>#include <map>#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=100000+10;int k;class Line{    public:    double x,yu,yd;    int type;    Line(){}    Line(double a,double b,double c,int d) :x(a),yu(b),yd(c),type(d) {}    bool operator <(const Line &a) const    {        return x<a.x;    }};vector<Line> line;vector<double> cor_y;map<double,int> pj;class SGtree{    public:    double len[MAXN<<2];    int cnt[MAXN<<2];    void build(int idx,int l,int r)    {        len[idx]=cnt[idx]=0;        if(l+1==r) return ;        build(lson);        build(rson);    }    void maintain(int idx,int l,int r)    {        if(cnt[idx]>0) len[idx]=cor_y[r]-cor_y[l];        else        {            if(l+1==r) len[idx]=0;            else len[idx]=len[lc]+len[rc];        }    }    void update(int idx,int l,int r,int x,int y,int v)    {        if(x<=l && r<=y)            cnt[idx]+=v;        else        {            if(x<mid) update(lson,x,y,v);            if(y>mid) update(rson,x,y,v);        }        maintain(whole);    }};SGtree tree;int main(){//    freopen("in","r",stdin);    int n,kcase=1;    while(~scanf("%d",&n) && n)    {        line.clear();        cor_y.clear();        pj.clear();        double a,b,c,d;        for(int i =0; i<n; i++)        {            scanf("%lf %lf %lf %lf",&a,&b,&c,&d);            line.push_back(Line(a,d,b,1));            line.push_back(Line(c,d,b,-1));            cor_y.push_back(b);            cor_y.push_back(d);        }        cor_y.push_back(-100000000);        sort(line.begin(),line.end());        sort(cor_y.begin(),cor_y.end());        k=1;        for(int i=1; i<cor_y.size(); i++)        {            if(cor_y[i]!=cor_y[i-1])            {                pj[cor_y[i]]=k;                cor_y[k++]=cor_y[i];            }        }        double ans=0;        tree.build(1,1,k-1);        tree.update(1,1,k-1,pj[line[0].yd],pj[line[0].yu],line[0].type);        for(int i=1; i<line.size(); i++)        {            ans+=(line[i].x-line[i-1].x)*(tree.len[1]);            tree.update(1,1,k-1,pj[line[i].yd],pj[line[i].yu],line[i].type);        }        printf("Test case #%d\n",kcase++);        printf("Total explored area: %.2f\n\n",ans) ;    }    return 0;}



0 0
原创粉丝点击