zoukankan      html  css  js  c++  java
  • POJ 1177Picture线段树+离散化+扫描线求矩形周长并

    周长并和面积并的代码基本上差不多,只不过多了两个rb,lb判定端点是否被覆盖的判断,维护的过程也增加了一点难度,但是整体上是差不多的。

    View Code
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include <algorithm>
    #define N 5005
    #define L(x) x<<1
    #define R(x) x<<1|1
    using namespace std;
    struct node
    {
        int l,r,num,len,cov;
        int lf,rf;
        bool rb,lb;
    };
    node tree[N<<2];
    struct seg
    {
        int x,y1,y2,flag;
    };
    seg line[N<<1];
    int y[N<<1],cnt;
    int cmp1(const void *a,const void *b)
    {
        return *(int *)a-*(int *)b;;
    }
    int cmp2(const void *a,const void *b)
    {
        seg *c=(seg *)a;
        seg *d=(seg *)b;
        return c->x-d->x;
    }
    void add(int x1,int x2,int y1,int y2)
    {
        line[cnt].x=x1,line[cnt].y1=y1,line[cnt].y2=y2,line[cnt].flag=1;
        cnt++;
        line[cnt].x=x2,line[cnt].y1=y1,line[cnt].y2=y2,line[cnt].flag=-1;
        cnt++;
    }
    void build(int l,int r,int i)
    {
        tree[i].l=l;
        tree[i].r=r;
        tree[i].num=tree[i].len=0;
        tree[i].rb=tree[i].lb=false;
        tree[i].cov=0;
        tree[i].lf=y[l];
        tree[i].rf=y[r];
        if(r==l+1)
        return;
        int mid=(l+r)>>1;
        build(l,mid,L(i));
        build(mid,r,R(i));
    }
    void length(int i)
    {
        if(tree[i].cov>0)
        {
            tree[i].len=tree[i].rf-tree[i].lf;
            tree[i].num=1;
            tree[i].rb=tree[i].lb=true;
            return;
        }
        else if(tree[i].l==tree[i].r-1)
        tree[i].num=tree[i].lb=tree[i].rb=tree[i].len=0;
        else
        {
            tree[i].rb=tree[R(i)].rb;
            tree[i].lb=tree[L(i)].lb;
            tree[i].len=tree[L(i)].len+tree[R(i)].len;
            tree[i].num=tree[L(i)].num+tree[R(i)].num-tree[L(i)].rb*tree[R(i)].lb;
        }
    }
    void update(seg l,int i)
    {
        if(tree[i].lf==l.y1&&tree[i].rf==l.y2)
        {
            tree[i].cov+=l.flag;
            length(i);
            return;
        }
        if(l.y2<=tree[L(i)].rf)
        update(l,L(i));
        else if(l.y1>=tree[R(i)].lf)
        update(l,R(i));
        else
        {
            seg temp;
            temp=l;
            temp.y2=tree[L(i)].rf;
            update(temp,L(i));
            temp=l;
            temp.y1=tree[R(i)].lf;
            update(temp,R(i));
        }
        length(i);
    }
    int main()
    {
        int n,i,j,x1,x2,y1,y2,m;
        while(~scanf("%d",&n))
        {
            cnt=0;
            m=0;
            for(i=0;i<n;i++)
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                y[m++]=y1;
                y[m++]=y2;
                add(x1,x2,y1,y2);
            }
            qsort(y,m,sizeof(int),cmp1);
            qsort(line,cnt,sizeof(seg),cmp2);
            int t=m;
            t=unique(y,y+m)-y;
            build(0,t-1,1);
            int lines,last,ans;
            lines=last=ans=0;
            line[cnt]=line[cnt-1];
            for(i=0;i<cnt;i++)
            {
                update(line[i],1);
                if(i)
                ans+=2*lines*(line[i].x-line[i-1].x);
                ans+=abs(tree[1].len-last);
                last=tree[1].len;
                lines=tree[1].num;
            }
            printf("%d\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    待解决问题集
    官方
    jsp 页面接收另一个页面传递过来的数据
    页面无法通过“${ctx}” 拿到值
    自定义 UsernamePasswordToken 报错 java.lang.ClassCastException: org.apache.shiro.authc.UsernamePasswordToken cannot be cast to
    springboot+mybatis map集合映射字段,当sql字段返回值为空时 不映射的问题
    java实现读写服务器文件
    前端模板免费下载网站
    The connection string contains invalid user information. If the username or password contains a colon (:) or an at-sign (@) then it must be urlencoded 解决方法
    springBoot -mongodb 小坑
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2636941.html
Copyright © 2011-2022 走看看