poj12482 扫描线+lazy-tag

采用扫描线的思想,其实是区间更新的题目

题解链接https://blog.csdn.net/shiqi_614/article/details/7819232

注意处理细节:1)因为边框上的点不算,所以要当出边入边重合时,要先更新出边,再更新入边

       2)同理,在y轴上建立的线段树应该把坐标离散成互不相交的点,如(0,1),(1,2),(2,3)等开区间来代替[0,1],[1,2],[2,3],这样就能避免算入边框上的点。

          怎么使用开区间?如果更新的线段是[1,2],那么实际上只能覆盖住[1,1]所以只要在update的两个分支中修改即可

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<map>
#define ll long long 
using namespace std;
#include<algorithm>
#define maxn 40005
#define lson l,m,rt<<1
#define rson m,r,rt<<1|1
struct Seg{
    ll x,y1,y2,c;
    Seg(){}
    Seg(ll a,ll b,ll c,ll d):x(a),y1(b),y2(c),c(d){}
    bool operator<(const Seg& a)const{
        if(x==a.x) return c<a.c;
        return x<a.x;
    }
}segs[maxn*2];

int w,h;
ll tot,toty,data[maxn];
map<ll,int> mp;//哈希表
int Max[maxn<<2],lazy[maxn<<2];//在y轴上建立线段树
inline void pushup(int rt){
    Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
}
inline void pushdown(int rt){
    if(lazy[rt]){
        Max[rt<<1]+=lazy[rt];
        Max[rt<<1|1]+=lazy[rt];
        lazy[rt<<1]+=lazy[rt];
        lazy[rt<<1|1]+=lazy[rt];
        lazy[rt]=0;
    }
}
void update(int L,int R,int c,int l,int r,int rt){
    if(L<=l && R>=r){
        lazy[rt]+=c;
        Max[rt]+=c;
        return;
    }
    pushdown(rt);
    int m=l+r>>1;
    if(L<m) update(L,R,c,lson);//离散化后要作为开区间处理
    if(R>m) update(L,R,c,rson);
    pushup(rt);
}
void init(){
    toty=tot=0;
    mp.clear();
    memset(Max,0,sizeof Max);
    memset(lazy,0,sizeof lazy);
}
int main(){
    ll n,a,b,c;
    while(scanf("%lld%d%d",&n,&w,&h)==3){
        init();
        for(int i=1;i<=n;i++){
            scanf("%lld%lld%lld",&a,&b,&c);
            segs[tot++]=Seg(a,b,b+h,c);segs[tot++]=Seg(a+w,b,b+h,-c);
            data[toty++]=b;data[toty++]=b+h;
        }
        sort(data,data+toty);
        sort(segs,segs+tot);
        toty=unique(data,data+toty)-data;
        for(int i=0;i<toty;i++) mp[data[i]]=i;//用map(哈希)离散化

        int mx=0;
        for(int i=0;i<tot;i++){
            update(mp[segs[i].y1],mp[segs[i].y2],segs[i].c,0,toty,1);
            mx=max(mx,Max[1]);
        }
        printf("%d
",mx);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zsben991126/p/9953706.html