• 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
    ",ans);
        return 0;
    }
  • 相关阅读:
    es6学习笔记
    vue.js项目目录结构说明
    js 数组操作总结
    js 数组去重方法
    HTTP协议三次握手过程
    MVC与MVVM模式对比
    谱面编辑器
    LL谱面分析和难度标定
    SLP的模块结构
    LL基本姿势
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9582020.html
Copyright © 2020-2023  润新知