zoukankan      html  css  js  c++  java
  • 扫描线

     

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn=2e5+10;                    //因为一个矩形有两边所以数据范围要乘2
    
    int y[maxn];
    
    struct L
    {
        int x;                                //竖边的x坐标
        int y1,y2;                            //竖边的y坐标,y1较小
        int state;                            //是左边还是右边
        bool operator<(const L &b)const       //排序时使用x坐标排序
        {
            return x<b.x;
        }
    } line[maxn];
    
    struct node                               //线段树
    {
        int l,r;                              //结点区间左右
        int cover;                            //被覆盖次数
        ll len;                               //区间真实长度
    } sgt[maxn<<3];                           //注意这个大小
    
    inline void pushup(int k)                 //与普通线段树的区别
    {
        if (sgt[k].cover)
        {
            sgt[k].len=sgt[k].r-sgt[k].l;
        }
        else
        {
            sgt[k].len=sgt[k<<1].len+sgt[k<<1|1].len;
        }
    }
    
    void build (int rt,int l,int r)
    {
        sgt[rt].l=y[l];
        sgt[rt].r=y[r];                         //与普通线段树的区别
        if (r-l<=1) return;                     //与普通线段树的区别
    
        int mid=(r+l)>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid,r);
    }
    
    void update(int rt,int x,int y,int z)
    {
        int l=sgt[rt].l,r=sgt[rt].r;
        if (x<=l&&r<=y)
        {
            sgt[rt].cover+=z;
            pushup(rt);
            return;
        }
        if (x<sgt[rt<<1].r) update(rt<<1,x,y,z);             //与普通线段树的区别
        if (y>sgt[rt<<1|1].l) update(rt<<1|1,x,y,z);         //与普通线段树的区别
        pushup(rt);
    }
    
    int main()
    {
        int n;
        scanf("%d",&n);
        for (int i=1,x1,x2,y1,y2; i<=n; i++)
        {
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            y[i]=y1;
            y[i+n]=y2;
            line[i]=L{x1,y1,y2,1};
            line[i+n]=L{x2,y1,y2,-1};
        }
        line[0].x=0;
        sort(y+1,y+1+n*2);
        sort(line+1,line+n*2+1);
        build (1,1,n<<1);
        ull ans=0;               //爆int的毒瘤数据只好用ull处理
        for (int i=1; i<=n<<1; i++)
        {
            ans+=1ull*sgt[1].len*(line[i].x-line[i-1].x);
            update(1,line[i].y1,line[i].y2,line[i].state);
        }
        printf("%llu
    ",ans);
        return 0;
    }
    

      

  • 相关阅读:
    pip安装超时
    MySQL+Android+JSP(php)的微博程序设计
    json的jar包
    eclipse远程连接不上数据库
    Dialog的Activity形式
    javaBean?
    Android生命周期详解
    四种启动模式
    softMax怎么更加方便地理解
    sqldevelpoer第一次使用出现错误的处理
  • 原文地址:https://www.cnblogs.com/Accpted/p/11367422.html
Copyright © 2011-2022 走看看