• [题解/模板]扫描线


    luogu_P1856矩形周长

    #include<bits/stdc++.h>
    #define ls (x<<1)
    #define rs (x<<1|1)
    //#define mid (l+r>>1)
    using namespace std;
    const int maxn=5009;
    const int maxm=10009;
    int n,ans;
    struct square{
        int xa,xb,ya,yb;
    }r[maxn];
    int hsh[maxn<<1],cnt;
    struct line{
        int l,r,h,f;
        bool operator <(const line&a)const{
            return h<a.h||h==a.h &&f>a.f;
        }
    }e[maxn<<1];
    struct node{
        int sum,tag;
    }t[maxm<<2];
    void upd(int x,int l,int r){
        if(t[x].tag)t[x].sum=hsh[r+1]-hsh[l];
        else if(l==r)t[x].sum=0;
        else t[x].sum=t[ls].sum+t[rs].sum;
    }
    void change(int x,int l,int r,int L,int R,int f){
        if(L<=l && r<=R){
            t[x].tag+=f;
            
        }
        else{
            int mid=(l+r)>>1;
            if(L<=mid)change(ls,l,mid,L,R,f);
            if(R>mid)change(rs,mid+1,r,L,R,f);
        }
        upd(x,l,r);
    }
    //int find(int x,int l,int r){
    //    while(l<=r){
    //        int mid=l+r>>1;
    //        if(hsh[mid]<x)l=mid+1;
    //        else if(hsh[mid]==x)return mid;
    //        else r=mid-1;
    //    }
    //}
    int solve(){
        int res=0;
        sort(hsh+1,hsh+1+cnt);
        sort(e+1,e+1+cnt);
        for(int i=1;i<=cnt;i++){
            int l=lower_bound(hsh+1,hsh+1+cnt,e[i].l)-hsh,
            r=lower_bound(hsh+1,hsh+1+cnt,e[i].r)-hsh-1;//这里要减一线段树维护的长度才正确 
    //        int l=find(e[i].l,1,cnt),r=find(e[i].r,1,cnt)-1;
            if(l<=r){
                int lst=t[1].sum;
                change(1,1,cnt,l,r,e[i].f);
                res+=abs(t[1].sum-lst);
            }
        }
        return res;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d%d%d%d",&r[i].xa,&r[i].ya,&r[i].xb,&r[i].yb);
            hsh[++cnt]=r[i].xa;e[cnt].l=r[i].xa;
            e[cnt].r=r[i].xb;e[cnt].h=r[i].ya;e[cnt].f=1;
            hsh[++cnt]=r[i].xb;e[cnt].l=r[i].xa;
            e[cnt].r=r[i].xb,e[cnt].h=r[i].yb,e[cnt].f=-1;
        }
        ans+=solve();
        cnt=0;
        for(int i=1;i<=n;i++){
            hsh[++cnt]=r[i].ya,e[cnt].l=r[i].ya;
            e[cnt].r=r[i].yb,e[cnt].h=r[i].xa,e[cnt].f=1;
            hsh[++cnt]=r[i].yb,e[cnt].l=r[i].ya;
            e[cnt].r=r[i].yb,e[cnt].h=r[i].xb,e[cnt].f=-1;
        }
        ans+=solve();
        printf("%d",ans);
    }

    POJ_1151_Atlantis

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define ls (x<<1)
    #define rs (x<<1|1)
    #define ll long long
    using namespace std;
    const int maxn=509;
    int n;
    double ans;
    struct node{
        double xa,xb,ya,yb;
    }r[maxn];
    double hsh[maxn<<1];int cnt;
    struct line{
        double l,r,h;
        int f;
        bool operator <(const line &a)const{
            return h<a.h || h==a.h && f>a.f;
        }
    }e[maxn<<1];
    struct tree{
        double sum;
        int tag;
    }t[maxn<<2];
    void upd(int x,int l,int r){
        if(t[x].tag)t[x].sum=hsh[r+1]-hsh[l];
        else if(l==r)t[x].sum=0;
        else t[x].sum=t[ls].sum+t[rs].sum;
    }
    void change(int x,int l,int r,int L,int R,int f){
        if(L<=l && r<=R){
            t[x].tag+=f;
        }
        else{
            int mid=l+r>>1;
            if(L<=mid)change(ls,l,mid,L,R,f);
            if(R>mid)change(rs,mid+1,r,L,R,f);
        }
        upd(x,l,r);
    }
    double solve(){
        double res=0;
        sort(hsh+1,hsh+1+cnt);
        sort(e+1,e+1+cnt);
        int tot=unique(hsh+1,hsh+1+cnt)-hsh-1;
        for(int i=1;i<cnt;i++){
            int l=lower_bound(hsh+1,hsh+1+tot,e[i].l)-hsh,
            r=lower_bound(hsh+1,hsh+1+tot,e[i].r)-hsh-1;
            if(l<=r){    
                change(1,1,tot,l,r,e[i].f);
            }res+=fabs(t[1].sum)*(e[i+1].h-e[i].h);
        }
        return res;
    }
    int main(){int tt=0;
        while(scanf("%d",&n) && n){tt++;
            cnt=0;
            memset(hsh,0,sizeof(hsh));
            memset(t,0,sizeof(t));
            for(int i=1;i<=n;i++){
                scanf("%lf%lf%lf%lf",&r[i].xa,&r[i].ya,&r[i].xb,&r[i].yb);
                hsh[++cnt]=r[i].xa;
                e[cnt].l=r[i].xa;
                e[cnt].r=r[i].xb;
                e[cnt].h=r[i].ya;
                e[cnt].f=1;
                hsh[++cnt]=r[i].xb;
                e[cnt].l=r[i].xa;
                e[cnt].r=r[i].xb;
                e[cnt].h=r[i].yb;
                e[cnt].f=-1;
            }
            printf("Test case #%d
    ",tt);
            printf("Total explored area: %.2f
    
    ",solve());
        }
    }
  • 相关阅读:
    Thinkphp框架下对某个字段查询数据的时候进行唯一过滤,返回唯一不同的值
    Thinkphp框架下(同服务器下)不同二级域名之间session互通共享设置
    CentOS 6.8下Apache绑定多个域名的方法
    CentOS 6.8下更改Apache默认网站安装目录
    Ubuntu 16.04系统下安装PHP5.6*
    Ubuntu 16.04系统下解决Vim乱码问题
    jQuery 核心
    Ubuntu 16.04系统下安装Discuz出现“HTTP ERROR 500”目前无法处理此请求
    BCB6 重装后的项目编译莫名问题
    LR6 碱性电池才能带动微软鼠标
  • 原文地址:https://www.cnblogs.com/superminivan/p/11468482.html
Copyright © 2020-2023  润新知