zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    抽象类与抽象方法
    简单工厂模式
    面向对象的七种基本设计原则
    HashTable集合遍历的三种方法
    继承(父类为虚方法以及子类的重写)
    继承(is与as)
    Chrome OS 更新新版本可让Linux访问USB连接的Android设备
    谷歌对Intel 10nm进度不满
    盖茨对没能做好手机系统对抗苹果表示遗憾
    微软内部封杀 Slack
  • 原文地址:https://www.cnblogs.com/zsben991126/p/9953706.html
Copyright © 2011-2022 走看看