省选专练 [USACO07OPEN]城市的地平线City Horizon

算法本质:求一堆矩形的交

依旧是扫描线

这里用线段树实现

离散化l,r

线段树维护区间最大值

然后把每个离散键值统计一下(如果没有离散,那个l,r一段是不会不同的)

#include<bits/stdc++.h>
using namespace std;
typedef int INT;
#define int long long 
#define lc (p<<1)
#define rc (p<<1|1)
const int N=2e5+100;
inline void read(int &x){
    x=0;
    int f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    x*=f;
}
struct Segment_tree{
    int lson,rson,mx,lazy;
}T[N<<2];
inline void PushUp(int p){
    T[p].mx=max(T[lc].mx,T[rc].mx);
}
inline void PushDown(int p){
    if(T[p].lazy){
        T[lc].mx=max(T[p].lazy,T[lc].mx);
        T[rc].mx=max(T[p].lazy,T[rc].mx);
        T[lc].lazy=max(T[p].lazy,T[lc].lazy);
        T[rc].lazy=max(T[p].lazy,T[rc].lazy);
        T[p].lazy=0;
    }
}
inline void build(int p,int l,int r){
    T[p].lson=l;
    T[p].rson=r;
    if(l==r){
        T[p].mx=0;
        return;
    }
    int mid=(l+r)/2;
    build(lc,l,mid);
    build(rc,mid+1,r);
    PushUp(p);
}
inline void update(int p,int l,int r,int val){
    if(l<=T[p].lson&&T[p].rson<=r){
        T[p].mx=max(T[p].mx,val);
        T[p].lazy=max(T[p].lazy,val);
        return;
    }
    PushDown(p);
    int mid=(T[p].lson+T[p].rson)/2;
    if(l<=mid)update(lc,l,r,val);
    if(mid< r)update(rc,l,r,val);
    PushUp(p);
}
inline int query(int p,int l,int r){
    if(l<=T[p].lson&&T[p].rson<=r){
        return T[p].mx;
    }
    PushDown(p);
    int mid=(T[p].lson+T[p].rson)/2;
    int ret=-1;
    if(l<=mid)ret=max(ret,query(lc,l,r));
    if(mid< r)ret=max(ret,query(rc,l,r));
    return ret;
}
int mmp[N]={};
int x[N]={};
int y[N]={};
int H[N]={};
int n;
int tot=0;
INT main(){
//	freopen("2352.in","r",stdin);
    read(n);
    for(int i=1;i<=n;i++){
        read(x[i]);
        read(y[i]);
        read(H[i]);
        mmp[++tot]=x[i];
        mmp[++tot]=y[i];
    }
    sort(mmp+1,mmp+1+tot);
    int len=unique(mmp+1,mmp+1+tot)-mmp-1;
    build(1,1,len+1);
//	cout<<len<<'\n';
//	cout<<"===="<<'\n';
    for(int i=1;i<=n;i++){
//		cout<<x[i]<<" "<<y[i]<<'\n';
        x[i]=lower_bound(mmp+1,mmp+1+len,x[i])-mmp;
        y[i]=lower_bound(mmp+1,mmp+1+len,y[i])-mmp;
//		cout<<x[i]<<" "<<y[i]<<" "<<H[i]<<'\n';
        update(1,x[i],y[i]-1,H[i]);
    }
    int ans=0;
    for(int i=2;i<=len;i++){
//		cout<<mmp[i]<<" ";
        ans+=query(1,i-1,i-1)*(mmp[i]-mmp[i-1]);
//		cout<<mmp[i-1]<<" "<<mmp[i]<<" H="<<query(1,i-1,i)<<'\n';
    }
    cout<<ans;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/fcb_x/article/details/81088867