美文网首页信息学竞赛题解(IO题解)
BZOJ-1935: [Shoi2007]Tree 园丁的烦恼(

BZOJ-1935: [Shoi2007]Tree 园丁的烦恼(

作者: AmadeusChan | 来源:发表于2018-10-16 20:28 被阅读0次

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

    首先二维前缀和是无力的,明显O( n^2 ),在线的二维BIT或SGT就更慢了,所以考虑离线。

    明显每个询问都可以拆成前缀和的形式,首先把所有点按y排序,然后从小到大扫一遍,每次将新的点加入到BIT中,顺便处理完这一层y的寻问,然后就没了。。。

    代码:

    3b292df5e0fe9925124bb52636a85edf8db17105.jpg.png
    #include <cstdio>
    
    #include <algorithm>
    
    #include <cstring>
    
     
    
    using namespace std ;
    
     
    
    #define MAXN 500010
    
    #define lowbit( x )((- x )& x )
    
     
    
    void getint(int&t ){
    
        int ch ;
    
        for( ch =getchar(  );!( ch >='0'&& ch <='9'); ch =getchar(  ));
    
        t = ch -'0';
    
        for( ch =getchar(  ); ch >='0'&& ch <='9'; ch =getchar(  )) t *=10, t += ch -'0';
    
    }
    
           
    
    void putint(int t ){
    
        if(! t )putchar('0')
    
        ;else{
    
            int ans[20];
    
            ans[0]=0;
    
            for(; t ; t /=10) ans[++ ans[0]]= t %10;
    
            for(int i = ans[0]; i ; i --)putchar('0'+ ans[ i ]);
    
        }
    
        putchar('\n');
    
    }
    
     
    
    struct Bit{
    
        int a[ MAXN *5], N ;
    
        
    
        void Init(int _N ){
    
            N = _N ;
    
            for(int i =0; i <= N ; i ++) a[ i ]=0;
    
        }
    
        
    
        void Add(int x ,int y ){
    
            for(int i = x ; i <= N ; i +=lowbit( i )) a[ i ]+= y ;
    
        }
    
        
    
        int Presum(int x ){
    
            int rec =0;
    
            for(int i = x ; i ; i -=lowbit( i )) rec += a[ i ];
    
            return rec ;
    
        }
    
        
    
        int Sum(int l ,int r ){
    
            return Presum( r )-Presum( l -1);
    
        }
    
        
    
    } bit ;
    
     
    
    struct point{
    
        int x , y ;
    
    } loc[ MAXN ];
    
     
    
    bool cmp( point x , point y ){
    
        return x.y < y.y ;
    
    }
    
     
    
    int n , m , que[ MAXN ][4];
    
    int cx[ MAXN *5], cy[ MAXN *5], bx[ MAXN *5], by[ MAXN *5], Vx =0, Vy =0, Nx =0, Ny =0;
    
     
    
    bool Cmp(int x ,int y ){
    
        return x < y ;
    
    }
    
     
    
    int Searchx(int x ){
    
        int l =1, r = Nx ;
    
        if( x == bx[ l ])return l ;
    
        if( x == bx[ r ])return r ;
    
        while(1){
    
            int mid =( l + r )>>1;
    
            if( bx[ mid ]== x )return mid ;
    
            if( x < bx[ mid ]) r = mid ;else l = mid ;
    
        }
    
    }
    
     
    
    int Searchy(int y ){
    
        int l =1, r = Ny ;
    
        if( y == by[ l ])return l ;
    
        if( y == by[ r ])return r ;
    
        while(1){
    
            int mid =( l + r )>>1;
    
            if( by[ mid ]== y )return mid ;
    
            if( y < by[ mid ]) r = mid ;else l = mid ;
    
        }
    
    }
    
     
    
    struct node{
    
        node *next ;
    
        int l , r , t , k ;
    
    }*head[ MAXN *5];
    
     
    
    void Insert(int y ,int l ,int r ,int t ,int k ){
    
        node *p =new( node );
    
        p -> l = l , p -> r = r , p -> t = t , p -> k = k , p -> next = head[ y ];
    
        head[ y ]= p ;
    
    }
    
     
    
    int ans[ MAXN ][2];
    
     
    
    int main(  ){
    
        getint( n ),getint( m );
    
        for(int i =0; i ++< n ;)getint( loc[ i ].x ),getint( loc[ i ].y );
    
        sort( loc +1, loc + n +1, cmp );
    
        for(int i =0; i ++< n ;){
    
            cx[++ Vx ]= loc[ i ].x , cy[++ Vy ]= loc[ i ].y ;
    
        }
    
        for(int i =0; i ++< m ;){
    
            getint( que[ i ][0]),getint( que[ i ][1]),getint( que[ i ][2]),getint( que[ i ][3]);
    
            cx[++ Vx ]= que[ i ][0], cx[++ Vx ]= que[ i ][2];
    
            cy[++ Vy ]= que[ i ][1]-1, cy[++ Vy ]= que[ i ][3];
    
        }
    
        sort( cx +1, cx + Vx +1, Cmp ),sort( cy +1, cy + Vy +1, Cmp );
    
        for(int i =0; i ++< Vx ;)if( i ==1|| cx[ i ]!= cx[ i -1]){
    
            bx[++ Nx ]= cx[ i ];
    
        }
    
        for(int i =0; i ++< Vy ;)if( i ==1|| cy[ i ]!= cy[ i -1]){
    
            by[++ Ny ]= cy[ i ];
    
        }
    
        memset( head ,0,sizeof( head ));
    
        for(int i =0; i ++< m ;){
    
            Insert(Searchy( que[ i ][1]-1), que[ i ][0], que[ i ][2], i ,0);
    
            Insert(Searchy( que[ i ][3]), que[ i ][0], que[ i ][2], i ,1);
    
        }
    
        bit.Init( Nx );
    
        int j =1;
    
        for(int i =0; i ++< Ny ;){
    
            for(; j <= n && loc[ j ].y <= by[ i ]; j ++) bit.Add(Searchx( loc[ j ].x ),1);
    
            for( node *p = head[ i ]; p ; p = p -> next ) ans[ p -> t ][ p -> k ]= bit.Sum(Searchx( p -> l ),Searchx( p -> r ));
    
        }
    
        for(int i =0; i ++< m ;)putint( ans[ i ][1]- ans[ i ][0]);
    
        return 0;
    
    }
    
    
    

    相关文章

      网友评论

        本文标题:BZOJ-1935: [Shoi2007]Tree 园丁的烦恼(

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