poj1151矩形面积并

来源:互联网 发布:linux文件管理web 编辑:程序博客网 时间:2024/06/09 20:06

学习了一种新的离散化

第一次写有关线段的线段树

个人理解的扫描线:每添加一条边(或权值)就算当前这一部分的东西,然后再添加,一个循环

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;#define MAXN 200int n,T,t;double x1,x2,y1,y2,ans;struct point{ double x,y1,y2; int flag;}node[2*MAXN];struct tpoint{   int l,r,s;   double len,ml,mr;}tree[4*MAXN];double y[2*MAXN];int comp(const point &a,const point &b){    return a.x<b.x+0.00000001;}//tree[p].len表示tree[p].ml~tree[p].mr之间被线段覆盖的总长度//tree[p].s表示tree[p].ml~tree[p].mr之间被几条线段覆盖//并且tree[p].s>0表示这条线段被完全覆盖void build(int p,int l,int r){    tree[p].l=l;    tree[p].r=r;    tree[p].ml=y[l];//离散化    tree[p].mr=y[r];    tree[p].s=0;    tree[p].len=0;    if (tree[p].l+1==tree[p].r)        return ;    int mid=(l+r) >> 1;    build(p<<1,l,mid);    build(p<<1^1,mid,r);}void callen(int p)//算tree[p].len{    if (tree[p].s>0)        tree[p].len=tree[p].mr-tree[p].ml;    else        if (tree[p].l+1==tree[p].r)          tree[p].len=0;        else           tree[p].len=tree[p<<1].len+tree[p<<1^1].len;    return ;}void updata(int p,point t){    if (tree[p].ml==t.y1 && tree[p].mr==t.y2)    {        tree[p].s+=t.flag;        callen(p);        return ;    }    double mid=tree[p<<1].mr;    if (t.y2<=mid) updata(p<<1,t);    if (t.y1>=mid) updata(p<<1^1,t);    if (t.y1<mid && t.y2>mid)    {        point tmp=t;        tmp.y2=mid;        updata(p<<1,tmp);        tmp=t;        tmp.y1=mid;        updata(p<<1^1,tmp);    }    callen(p);//每一次更新了tree[p]的子节点,就要更新p的len,保证每次只取tree[1].len即可    return ;}int main(){    while (scanf("%d", &n) && (n))    {        T++;        t=0;        for (int i=1;i<=n;i++)        {            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);            t++;            y[t]=y1;            node[t].x=x1;            node[t].y1=y1;            node[t].y2=y2;            node[t].flag=1;            t++;            y[t]=y2;            node[t].x=x2;            node[t].y1=y1;            node[t].y2=y2;            node[t].flag=-1;        }        sort(node+1,node+t+1,comp);        sort(y+1,y+t+1);        build(1,1,t);        ans=0;        updata(1,node[1]);        for (int i=2;i<=t;i++)        {            ans+=(node[i].x-node[i-1].x)*tree[1].len;            updata(1,node[i]);        }        printf("Test case #%d\n",T);        printf("Total explored area: %.2lf\n\n",ans);    }    return 0;}


0 0