POJ 3277 线段树+扫描线

题意:
这里写图片描述
思路:
线段树求矩形面积的并。。。同 POJ 1151

//By SiriusRen
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 88888
int n,u,tot,xx,yy,h[N];
long long ans;
struct Node{int x,h,cover;}node[4*N];
struct Tree{int l,r,cover,len;}tree[4*N];
bool cmp(Node a,Node b){return a.x<b.x;}
void build(int l,int r,int pos){
    tree[pos].l=h[l],tree[pos].r=h[r];
    if(r==l+1)return;
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
    build(l,mid,lson),build(mid,r,rson);
}
void push_up(int l,int r,int pos){
    if(tree[pos].cover)tree[pos].len=tree[pos].r-tree[pos].l;
    else if(l+1==r)tree[pos].len=0;
    else tree[pos].len=tree[pos<<1].len+tree[pos<<1|1].len;
}
void insert(int l,int r,int pos,Node jy){
    if(tree[pos].r<=jy.h){tree[pos].cover+=jy.cover,push_up(l,r,pos);return;}
    int mid=(l+r)>>1,lson=pos<<1,rson=pos<<1|1;
    if(tree[lson].r>=jy.h)insert(l,mid,lson,jy);
    else insert(l,mid,lson,jy),insert(mid,r,rson,jy);
    push_up(l,r,pos);
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&xx,&yy,&h[i]);
        node[++tot].x=xx,node[tot].h=h[i],node[tot].cover=1;
        node[++tot].x=yy,node[tot].h=h[i],node[tot].cover=-1;
    }
    sort(node+1,node+1+tot,cmp),sort(h+1,h+1+n);
    u=unique(h+1,h+1+n)-h-1;
    build(0,u,1),insert(0,u,1,node[1]);
    for(int i=2;i<=tot;i++){
        ans+=(long long)(node[i].x-node[i-1].x)*tree[1].len;
        insert(0,u,1,node[i]);
    }
    printf("%lld
",ans);
}

这里写图片描述

原文地址:https://www.cnblogs.com/SiriusRen/p/6532274.html