BZOJ-1062: [NOI2008]糖果雨(二维树状数组)

作者: AmadeusChan | 来源:发表于2019-03-15 09:50 被阅读0次

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1062

    首先把每个云抽象成一个点(x,y),表示该云在mod 2len意义下到达最左端的时间为x和长度为y,那么我们发现统计的时候可以补成统计两块平行四边形的点,那么坐标转一下,对于每个平行四边形,分别把坐标轴旋转45度,这样就变成了矩形,可以方便的用BIT统计了。

    代码(细节超多,注意边界的重复):

    #include <cstdio>
    
    #include <algorithm>
    
    #include <cstring>
    
     
    
    using namespace std ;
    
     
    
    #define REP( i , l , r ) for ( int i = l ; i <= r ; ++ i )
    
    #define rep( i , x ) for ( int i = 0 ; i ++ < x ; )
    
    #define Rep( i , x ) for ( int i = 0 ; i < x ; ++ i )
    
     
    
    const int maxc = 1010000 ;
    
    const int maxl = 1005 ;
    
     
    
    struct BIT {
    
        int N , M , T[ maxl * 2 ][ maxl * 5 ] ;
    
        inline void Init( int _N , int _M ) {
    
            N = _N , M = _M ;
    
            rep( i , N ) rep( j , M ) T[ i ][ j ] = 0 ;
    
        }
    
        #define lowbit( x ) ( ( - x ) & x )
    
        inline void add( int x , int y , int v ) {
    
            for ( int i = x ; i <= N ; i += lowbit( i ) ) {
    
                for ( int j = y ; j <= M ; j += lowbit( j ) ) {
    
                    T[ i ][ j ] += v ;
    
                }
    
            }
    
        }
    
        inline int query( int x , int y ) {
    
            int sum = 0 ;
    
            for ( int i = x ; i ; i -= lowbit( i ) ) {
    
                for ( int j = y ; j ; j -= lowbit( j ) ) {
    
                    sum += T[ i ][ j ] ;
    
                }
    
            }
    
            return sum ;
    
        }
    
        inline int Query( int lx , int rx , int ly , int ry ) {
    
            if ( lx > rx || ly > ry ) return 0 ;
    
            int rec = query( rx , ry ) + query( lx - 1 , ly - 1 ) ;
    
            int ret = query( lx - 1 , ry ) + query( rx , ly - 1 ) ;
    
            return rec - ret ;
    
        }
    
    } bit[ 2 ] ;
    
     
    
    int n , len , cl[ maxc ][ 2 ] ;
    
     
    
    inline void trans0( int &x , int &y ) {
    
        y = y - x ; x ++ , y += 3 * len ; 
    
    }
    
     
    
    inline void trans1( int &x , int &y ) {
    
        y = x + y ; x ++ , y += ( len + 1 ) ;
    
    }
    
     
    
    inline void change0( int x , int y , int v ) {
    
        trans0( x , y ) ; bit[ 0 ].add( x , y , v ) ;
    
    }
    
     
    
    inline void change1( int x , int y , int v ) {
    
        trans1( x , y ) ; bit[ 1 ].add( x , y , v ) ;
    
    }
    
     
    
    inline void modify( int t , int c , int l , int r , int d ) {
    
        int x = ( t - d * l + len * 2 ) % ( len * 2 ) ;
    
        int y = r - l ;
    
        cl[ c ][ 0 ] = x , cl[ c ][ 1 ] = y ;
    
        change0( x , y , 1 ) , change1( x , y , 1 ) ;
    
    }
    
     
    
    inline int query( int t , int l , int r ) {
    
        t %= ( len << 1 ) ;
    
        int ans = 0 ;
    
        if ( t >= r ) {
    
            int lx = t - r , rx = t , ly = l - r , ry = len + r ;
    
            trans0( lx , ly ) , trans0( rx , ry ) ;
    
            ans += bit[ 0 ].Query( lx , rx , ly , ry ) ;
    
        } else {
    
            int lx = 0 , rx = t , ly = l - t , ry = len + r ;
    
            trans0( lx , ly ) , trans0( rx , ry ) ;
    
            ans += bit[ 0 ].Query( lx , rx , ly , ry ) ;
    
            lx = 2 * len - ( r - t ) , rx = 2 * len - 1 ;
    
            ly = l - r , ry = len + r - t - 1 ;
    
            trans0( lx , ly ) , trans1( rx , ry ) ;
    
            ans += bit[ 0 ].Query( lx , rx , ly , ry ) ;   
    
        }
    
        if ( ! r ) return ans ;
    
        if ( t + r < 2 * len ) {
    
            int lx = t + 1 , rx = t + r , ly = l - 1 , ry = len ;
    
            if ( r == len ) -- rx , ++ ry ;
    
            trans1( lx , ly ) , trans1( rx , ry ) ;
    
            ans += bit[ 1 ].Query( lx , rx , ly , ry ) ;
    
        } else {
    
            int lx , rx , ly , ry ;
    
            if ( t + 1 < 2 * len ) {
    
                lx = t + 1 , rx = 2 * len - 1 ;
    
                ly = l - 1 , ry = r - len + t + 2 ;
    
                trans1( lx , ly ) , trans1( rx , ry ) ;
    
                ans += bit[ 1 ].Query( lx , rx , ly , ry ) ;
    
            }
    
            lx = 0 , rx = t + r - 2 * len ;
    
            ly = l - 2 * len + t , ry = len ;
    
            if ( r == len ) -- rx , ++ ry ;
    
            trans1( lx , ly ) , trans1( rx , ry ) ;
    
            ans += bit[ 1 ].Query( lx , rx , ly , ry ) ;
    
        }
    
        return ans ;
    
    }
    
     
    
    inline void Delete( int c ) {
    
        int x = cl[ c ][ 0 ] , y = cl[ c ][ 1 ] ;
    
        trans0( x , y ) ; bit[ 0 ].add( x , y , -1 ) ;
    
        x = cl[ c ][ 0 ] , y = cl[ c ][ 1 ] ;
    
        trans1( x , y ) ; bit[ 1 ].add( x , y , -1 ) ;
    
    }
    
     
    
    int main(  ) {
    
        scanf( "%d%d" , &n , &len ) ;
    
        bit[ 0 ].Init( 2 * len , 5 * len ) , bit[ 1 ].Init( 2 * len , 5 * len ) ;
    
        int type , t , l , r , d , c ;
    
        rep( i , n ) {
    
            scanf( "%d" , &type ) ;
    
            switch ( type ) {
    
                case 1 :
    
                    scanf( "%d%d%d%d%d" , &t , &c , &l , &r , &d ) ; modify( t , c , l , r , d ) ;
    
                    break ;
    
                case 2 :
    
                    scanf( "%d%d%d" , &t , &l , &r ) ; printf( "%d\n" , query( t , l , r ) ) ;
    
                    break ;
    
                case 3 :
    
                    scanf( "%d%d" , &t , &c ) ; Delete( c ) ;
    
                    break ;
    
            }
    
        }
    
        return 0 ;
    
    }
    

    相关文章

      网友评论

        本文标题:BZOJ-1062: [NOI2008]糖果雨(二维树状数组)

        本文链接:https://www.haomeiwen.com/subject/hbnkmqtx.html