• 610D


    扫描线:http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html

    看图,图中的数字是横坐标离散后对应的下标,计算时左端点不变,右端点加1,所以总的更新的区间是l到r-1。

    也可以理解为1代表的是(1到2这一段),2代表的是(2到3这一段),3代表的是(3到4这一段)。。。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    #define ls rt<<1,l,m
    #define rs rt<<1|1,m+1,r
    #define mem(a,b) memset(a,b,sizeof(a))
    
    const int N=1e5+5;
    struct line
    {
        int x1,x2;
        int h;
        int cover;
        bool operator < (const line &t)
        {
            return h<t.h;
        }
    };
    vector<line>l;
    vector<int>w;
    struct Tree
    {
        int l,r;
        int sum;
        int cover;
    }tree[N*8];
    
    void push_up(int rt)
    {
        if(tree[rt].cover)
        {
            tree[rt].sum=w[tree[rt].r+1]-w[tree[rt].l];
        }
        else
        {
            if(tree[rt].l==tree[rt].r)tree[rt].sum=0;
            else tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
        }
    }
    
    void build(int rt,int l,int r)
    {
        tree[rt].sum=tree[rt].cover=0;
        tree[rt].l=l,tree[rt].r=r;
        if(l==r)return ;
        int m=(l+r)>>1;
        build(ls);
        build(rs);
    }
    
    void Update(int L,int R,int delta,int rt,int l,int r)
    {
        if(L<=l&&r<=R)
        {
            tree[rt].cover+=delta;
            push_up(rt);
            return ;
        }
        int m=(l+r)>>1;
        if(L<=m)Update(L,R,delta,ls);
        if(R>m)Update(L,R,delta,rs);
        push_up(rt);
    }
    
    
    int binasrh(int val,int l,int r)
    {
        int m;
        while(l<=r)
        {
             m=(l+r)>>1;
             if(w[m]==val)return m;
             else if(w[m]<val)l=m+1;
             else r=m-1;
        }
        return -1;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int n,x1,x2,y1,y2;
        cin>>n;
        for(int i=0;i<n;i++)
        {
            cin>>x1>>y1>>x2>>y2;
            if(x1>x2||y1>y2)
            {
                swap(x1,x2);
                swap(y1,y2); 
            }
            x2++;
            y2++;
            l.pb(line{x1,x2,y1,1});
            l.pb(line{x1,x2,y2,-1});
            w.pb(x1);
            w.pb(x2);
        } 
        sort(w.begin(),w.end());
        sort(l.begin(),l.end());
        w.erase(unique(w.begin(),w.end()),w.end());
        
        ll ans=0;
        build(1,0,w.size()-1);
        for(int i=0;i<l.size()-1;i++)
        {
            int L=binasrh(l[i].x1,0,w.size()-1);
            int R=binasrh(l[i].x2,0,w.size()-1);
            if(L<R)Update(L,R-1,l[i].cover,1,0,w.size()-1);
            ans+=(ll)tree[1].sum*(l[i+1].h-l[i].h);
        }
        
        cout<<ans<<endl;
        return 0; 
    } 
  • 相关阅读:
    svn 搭建及环境测试 详细
    mysql 开启用户远程登录
    Linux svn 搭建
    Subversion(svn) 简介
    pytest快速入门(1)--pytest与unittest的比较总揽
    python自动化测试(8)--json字符串与dict之间的相互转换
    web自动化测试(2)--使用xpath实现页面元素的定位
    web自动化测试(1)--web页面元素的8种定位方法
    性能测试入门(1)--性能测试关键指标
    python自动化测试(6)--测试流程mark
  • 原文地址:https://www.cnblogs.com/widsom/p/7575633.html
Copyright © 2020-2023  润新知