HDU-3949 XOR 线性基

来源:互联网 发布:动物头挡脸的软件 编辑:程序博客网 时间:2024/06/17 18:29

大家都很强, 可与之共勉 。

题意:
求一个数列能够异或出来的第k大元素。

线性基裸题,学习笔记之后补上。

UPD2017.12.4:线性基学习笔记

# include <cstdio># include <vector>const int MAXN = 100000;const int MAXL = 63;struct LinearBasis  {    int n ;    std :: vector < long long > a, v ;    void build ( long long *x, int n )  {        this -> n = n ;        a.clear ( ) ;        a.resize ( MAXL + 1 ) ;         for ( int i = 1 ; i <= n ; ++ i )  {            long long t = x [i] ;            for ( int j = MAXL ; j >= 0 ; -- j ) {                if ( ( t & (1LL << j ) ) == 0 ) continue ;                if ( a [j] ) t ^= a [j] ;                else  {                    for ( int k = 0 ; k < j ; ++ k ) if ( t & ( 1LL << k ) ) t ^= a [k] ;                    for ( int k = j + 1 ; k <= MAXL ; ++ k ) if ( a [k] & ( 1LL << j ) ) a [k] ^= t ;                    a [j] = t ;                    break ;                }            }        }        v.clear ( ) ;        for ( int i = 0 ; i <= MAXL ; ++ i ) if ( a [i] ) v.push_back ( a [i] ) ;    }    long long query ( long long k )  {        if ( int ( v.size ( ) ) != n )  -- k ;  // maybe zero ;        if ( k > ( 1LL << v.size ( ) ) - 1 ) return -1 ;  // illegal ;        long long ans = 0 ;        for ( size_t i = 0; i < v.size ( ) ; ++ i )            if ( k & ( 1LL << i ) )  {                ans ^= v [i] ;            }        return ans ;    }} lb ;int main ( )  {    int T ;    scanf ( "%d", & T ) ;    for ( int cas = 1 ; cas <= T ; ++ cas )  {        int n ;        scanf ( "%d", & n ) ;        static long long a [MAXN + 1] ;        for ( int i = 1 ; i <= n ; ++ i ) scanf ( "%lld", a + i ) ;        lb.build ( a, n ) ;        printf ( "Case #%d:\n", cas ) ;        int m ;        scanf ( "%d", & m ) ;        while ( m -- )  {            static long long k ;            scanf ( "%lld", & k ) ;            printf ( "%lld\n", lb.query ( k ) ) ;        }    }    return 0 ;}
原创粉丝点击