Picture

求给出矩形的周长。

这是一道周长扫描线题,比较裸。juruo第一次打打了一个多小时。

代码:

#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 5005
int n,tot;
struct EDge
{
    int l,r,s,v;
    EDge(){}
    EDge(int l,int r,int s,int v):l(l),r(r),s(s),v(v){}
    friend bool operator < (EDge a,EDge b)
    {
        if(a.s!=b.s)return a.s<b.s;
        return a.v>b.v;
    }
}ex[2*N];
struct Segtree
{
    int sum;
    int num;
    int len;
    bool lfg,rfg;
}tr[80005];
void update(int u,int l,int r)
{
    if(tr[u].sum)
    {
        tr[u].num=1;
        tr[u].len=r-l+1;
        tr[u].lfg=tr[u].rfg=1;
    }else if(l==r)
    {
        tr[u].num=0;
        tr[u].len=0;
        tr[u].lfg=tr[u].rfg=0;
    }else
    {
        tr[u].num=tr[u<<1].num+tr[u<<1|1].num;
        tr[u].len=tr[u<<1].len+tr[u<<1|1].len;
        if(tr[u<<1].rfg&&tr[u<<1|1].lfg)tr[u].num--;
        tr[u].lfg=tr[u<<1].lfg;
        tr[u].rfg=tr[u<<1|1].rfg;
    }
}
void Insert(int l,int r,int u,int ql,int qr,int v)
{
    if(l==ql&&r==qr)
    {
        tr[u].sum+=v;
        update(u,l,r);
        return ;
    }
    int mid = (l+r)>>1;
    if(qr<=mid)Insert(l,mid,u<<1,ql,qr,v);
    else if(ql>mid)Insert(mid+1,r,u<<1|1,ql,qr,v);
    else Insert(l,mid,u<<1,ql,mid,v),Insert(mid+1,r,u<<1|1,mid+1,qr,v);
    update(u,l,r);
}
int main()
{
    scanf("%d",&n);
    int x_1,y_1,x_2,y_2,mn=0x7fffffff,mx=-0x7fffffff;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d%d",&x_1,&y_1,&x_2,&y_2);
        ex[++tot]=EDge(x_1,x_2,y_1,1);
        ex[++tot]=EDge(x_1,x_2,y_2,-1);
        mx=max(mx,max(x_1,x_2));
        mn=min(mn,min(x_1,x_2));
    }
    if(mn<=0)
    {
        for(int i=1;i<=tot;i++)ex[i].l-=mn-1,ex[i].r-=mn-1;
        mx-=mn-1;
    }
    sort(ex+1,ex+tot+1);
    int ans = 0,las = 0;
    for(int i=1;i<=tot;i++)
    {
        Insert(1,mx,1,ex[i].l,ex[i].r-1,ex[i].v);
        while(ex[i+1].s==ex[i].s&&ex[i+1].v==ex[i].v)
        {
            i++;
            Insert(1,mx,1,ex[i].l,ex[i].r-1,ex[i].v);
        }
        ans+=abs(tr[1].len-las);
        las =tr[1].len;
        ans+=tr[1].num*2*(ex[i+1].s-ex[i].s);
    }
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2018-09-04 00:28  LiGuanlin  阅读(201)  评论(0编辑  收藏  举报