美文网首页信息学竞赛题解(IO题解)
BZOJ-2120: 数颜色(BIT套SBT)

BZOJ-2120: 数颜色(BIT套SBT)

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

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

    写裸数据结构题最开心啦~~~

    维护一下与每个位置颜色一样的前面和后面最近的数,不存在则设为无穷,然后每次查询就等价于查询该区间后缀大于r的数有多少个,然后就各种BST暴力维护就可以啦。

    代码(差点就超时了。。。):

    d788d43f8794a4c2817d01480cf41bd5ad6e3973.jpg.png
    #include <cstdio>
    
    #include <algorithm>
    
    #include <cstring>
    
    #include <set>
    
     
    
    using namespace std ;
    
     
    
    #define MAXN 10010
    
    #define inf 0x7fffffff
    
    #define MAXC 1000100
    
    #define MAXV 500010
    
    #define L( t ) t -> left
    
    #define R( t ) t -> right
    
    #define K( t ) t -> key
    
    #define S( t ) t -> size
    
    #define update( t )S( t )=S(L( t ))+S(R( t ))+1
    
    #define lowbit( t )((- t )& t )
    
     
    
    struct SBT{
    
         
    
        struct node{
    
            node *left ,*right ;
    
            int key , size ;
    
        }*roof ,*null ;
    
         
    
        SBT(  ){
    
            roof = null =new( node );
    
            S( null )=0,L( null )=R( null )= null ;
    
        }
    
         
    
        void left( node*&t ){
    
            node *k =R( t );
    
            R( t )=L( k );update( t );
    
            L( k )= t ;update( k );
    
            t = k ;
    
        }
    
         
    
        void right( node*&t ){
    
            node *k =L( t );
    
            L( t )=R( k );update( t );
    
            R( k )= t ;update( k );
    
            t = k ;
    
        }
    
         
    
        void maintain( node*&t ){
    
            if(S(L(L( t )))>S(R( t ))){
    
                right( t );
    
                maintain(R( t ));maintain( t );
    
                return;
    
            }
    
            if(S(R(L( t )))>S(R( t ))){
    
                left(L( t ));right( t );
    
                maintain(L( t )),maintain(R( t ));maintain( t );
    
                return;
    
            }
    
            if(S(R(R( t )))>S(L( t ))){
    
                left( t );
    
                maintain(L( t ));maintain( t );
    
                return;
    
            }
    
            if(S(L(R( t )))>S(L( t ))){
    
                right(R( t ));left( t );
    
                maintain(L( t )),maintain(R( t ));maintain( t );
    
                return;
    
            }
    
        }
    
         
    
        void Insert(int k , node*&t ){
    
            if( t == null ){
    
                t =new( node );
    
                L( t )=R( t )= null ,S( t )=1,K( t )= k ;
    
                return;
    
            }
    
            Insert( k , k <K( t )?L( t ):R( t ));
    
            update( t );maintain( t );
    
        }
    
         
    
        void Delete(int k , node*&t ){
    
            if( k ==K( t )){
    
                if(L( t )== null ){
    
                    node *u = t ;
    
                    t =R( t );
    
                    delete( u );
    
                    return;
    
                }else if(R( t )== null ){
    
                    node *u = t ;
    
                    t =L( t );
    
                    delete( u );
    
                    return;
    
                }else{
    
                    right( t );
    
                    Delete( k ,R( t ));
    
                }
    
            }else Delete( k , k <K( t )?L( t ):R( t ));
    
            update( t );maintain( t );
    
        }
    
          
    
        int rank(int k , node *t ){
    
            if( t == null )return 0;
    
            return k <K( t )?rank( k ,L( t ))+S(R( t ))+1:rank( k ,R( t ));
    
        }
    
         
    
        void Push(int k ){
    
            Insert( k , roof );
    
        }
    
         
    
        void Erase(int k ){
    
            Delete( k , roof );
    
        }
    
         
    
        int Rank(int k ){
    
            return rank( k , roof );
    
        }
    
         
    
    } sbt[ MAXN ];
    
     
    
    set <int> rbt[ MAXC ];
    
     
    
    int n , m , a[ MAXN ], suff[ MAXN ];
    
     
    
    void Insert_bit(int pos ,int k ){
    
        for(int i = pos ; i <= n ; i +=lowbit( i )) sbt[ i ].Push( k );
    
    }
    
     
    
    void Delete_bit(int pos ,int k ){
    
        for(int i = pos ; i <= n ; i +=lowbit( i )) sbt[ i ].Erase( k );
    
    }
    
     
    
    int Rank_bit(int pos ,int k ){
    
        int rec =0;
    
        for(int i = pos ; i ; i -=lowbit( i )) rec += sbt[ i ].Rank( k );
    
        return rec ;
    
    }
    
     
    
    int main(  ){
    
        scanf("%d%d",&n ,&m );
    
        for(int i =0; i ++< n ;)scanf("%d",&a[ i ]);
    
        for(int i =0; i ++< MAXC -1;){
    
            rbt[ i ].clear(  );
    
            rbt[ i ].insert(- inf ), rbt[ i ].insert( inf );
    
        }
    
        for(int i =0; i ++< n ;) rbt[ a[ i ]].insert( i );
    
        for(int i =0; i ++< n ;) suff[ i ]=*(++ rbt[ a[ i ]].lower_bound( i ));
    
        for(int i =0; i ++< n ;)Insert_bit( i , suff[ i ]);
    
        while( m --){
    
            int ch , l , r ;for( ch =getchar(  );!( ch =='Q'|| ch =='R'); ch =getchar(  ));
    
            if( ch =='Q'){
    
                scanf("%d%d",&l ,&r );
    
                printf("%d\n",Rank_bit( r , r )-Rank_bit( l -1, r ));
    
            }else{
    
                scanf("%d%d",&l ,&r );
    
                int k =*(-- rbt[ a[ l ]].lower_bound( l ));
    
                if( k >- inf ){
    
                    Delete_bit( k , suff[ k ]);
    
                    Insert_bit( k , suff[ k ]= suff[ l ]);
    
                }
    
                rbt[ a[ l ]].erase( l );
    
                Delete_bit( l , suff[ l ]);
    
                a[ l ]= r ;
    
                rbt[ r ].insert( l );
    
                set <int>:: iterator u = rbt[ r ].lower_bound( l );
    
                k =*(-- u );
    
                if( k >- inf ){
    
                    Delete_bit( k , suff[ k ]);
    
                    Insert_bit( k , suff[ k ]= l );
    
                }
    
                suff[ l ]=*(++ rbt[ r ].lower_bound( l ));
    
                Insert_bit( l , suff[ l ]);
    
            }
    
        }
    
        return 0;
    
    }
    

    相关文章

      网友评论

        本文标题:BZOJ-2120: 数颜色(BIT套SBT)

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