[题解/模板]扫描线

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\n",tt);
        printf("Total explored area: %.2f\n\n",solve());
    }
}

 

posted @ 2019-09-05 17:28  羊肉汤泡煎饼  阅读(141)  评论(0编辑  收藏  举报