C2 - Heidi and the Turing Test (Medium)

 考虑一个矩形可覆盖一个点的矩形的右上角的位置,我们发现是一个矩形。那么被矩形覆盖次数最多的点就是矩形的右上角。

问题转化为被矩形覆盖次数最多的矩形被覆盖了多少次。

    #include 
    #define lc l,mid,x<<1
    #define rc mid+1,r,x<<1|1
    using namespace std;
    typedef long long LL;
    typedef int lint;
    const lint dt = 2000010;
    void trans( lint& x,lint& y ){
        lint xx = x,yy = y;
        x = xx-yy+dt; y = xx+yy+dt;
    }
    struct Point{
        lint x,y,c;
        Point( lint xx = 0,lint yy = 0,lint cc = 0 ){
            x = xx;y = yy;c=cc;
        }
        bool operator <( const Point& b )const{
            if( y == b.y ){
                if( x == b.x ) return c < b.c;
                return x < b.x;
            }
            return y < b.y;
        }
    };
    vector ve;
    lint tree[16*dt],laz[16*dt];
    void push_down( lint x ){
        if( laz[x] ){
            tree[x<<1] += laz[x];
            tree[x<<1|1]+=laz[x];
            laz[x<<1]+= laz[x];
            laz[x<<1|1]+=laz[x];
            laz[x]=0;
        }
        return;
    }
    void push_up( lint x ){
        tree[x] = max(tree[x<<1] , tree[x<<1|1]);
    }
    void update( lint ll,lint rr,lint v,lint l,lint r,lint x ){
        if( ll <= l && rr >= r ){
            tree[x] += v;
            laz[x] += v;
            return;
        }
        push_down(x);
        lint mid = l + r>>1;
        if( ll <= mid ) update( ll,rr,v,lc );
        if( rr > mid ) update( ll,rr,v,rc );
        push_up(x);
    }
    lint query( lint ll,lint rr,lint l,lint r,lint x ){
     
        if( ll <= l && rr >= r ){
            return tree[x] ;
        }
        push_down(x);
        lint mid = l+r>>1;
        lint res = 0;
        if(ll<= mid)  res = max(res, query( ll,rr,lc ));
        if(rr>mid) res = max(res,query(ll,rr,rc));
        push_up(x);
        return res;
    }
    int main(){
        lint n,r,ans = 0;
        scanf("%d%d",&n,&r);
        for( lint x,y,i = 1;i <= n;i++ ){
            scanf("%d%d",&x,&y);
            trans(x,y);
            ve.push_back( Point( x,y,0 ) );ve.push_back( Point( x+2*r,y+2*r,1 ) );
        }
        sort( ve.begin(),ve.end() );
        for( lint i= 0 ;i< ve.size();i++ ){
            Point cur=  ve[i];
            if( cur.c == 0 ){
                update( cur.x,cur.x+2*r,1,0,4*dt,1 );
                lint res = query( 0,4*dt,0,4*dt,1 );
                ans = max( ans,res );
            }else{
                lint res = query( 0,4*dt,0,4*dt,1 );
                ans = max( ans,res );
                update( cur.x-2*r ,cur.x,-1,0,4*dt,1 );
            }
        }
        printf("%d",ans);
        return 0;
    }

 

你可能感兴趣的:(线段树,线段树)