美文网首页信息学竞赛题解(IO题解)
BZOJ-2729: [HNOI2012]排队(排列组合+高精度

BZOJ-2729: [HNOI2012]排队(排列组合+高精度

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

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

    裸的排列组合,用插空法,先加男生,再加老师,再加女生,易得答案:

    Ans( n , m ) = A( n , n ) [ A( 2 , n + 1 ) A( m , n + 3 ) + A( 1 , n + 1 ) A( 2 , 2 ) A( 1 , m ) A( m - 1 , n + 2 ) ]

    化简:

    Ans( n , m ) = n! ( n + 1 ) [ ( n - m + 4 ) ( n - m + 5 ) ... ( n + 2 ) ] [ ( n + 3 ) n + 2 m ]

    然后就用高精度乘法算就可以啦~

    代码:


    838ba61ea8d3fd1f3774ac59324e251f95ca5f57.jpg.png

    压了4位,速度还是这么慢。。。话说那些100+ms是怎么达到的?难道都是敲了FFT!!!?

    #include <cstdio>
    
    #include <algorithm>
    #include <cstring>
     
    using namespace std ;
     
    #define MAXN 3010
    #define MAX 10000
     
    struct BigNumber {
         
        int a[ MAXN ] , m ;
         
        void Transform( int t ) {
            m = 0 ;
            if ( ! t ) {
                a[ m = 1 ] = 0 ;
            } else {
                for ( ; t ; t /= MAX ) a[ ++ m ] = t % MAX ;
            }
        }
         
        void Print(  ) {
            for ( int i = m ; i ; i -- ) {
                if ( i != m ) {
                    if ( a[ i ] < 1000 ) printf( "0" ) ;
                    if ( a[ i ] < 100 ) printf( "0" ) ;
                    if ( a[ i ] < 10) printf( "0" ) ;
                }
                printf( "%d" , a[ i ] ) ;
            }
            printf( "\n" ) ;
        }
         
    } ans , rec ;
     
    int n , m ;
     
    BigNumber Multiply( BigNumber x , BigNumber y ) {
        BigNumber ret ; ret.m = 0 ;
        memset( ret.a , 0 , sizeof( ret.a ) ) ;
        for ( int i = 0 ; i ++ < x.m ; ) {
            for ( int j = 0 ; j ++ < y.m ; ) {
                ret.a[ i + j - 1 ] += x.a[ i ] * y.a[ j ] ;
                ret.m = max( ret.m , i + j - 1 ) ;
                for ( int k = i + j - 1 ; ret.a[ k ] >= MAX ; k ++ ) {
                    ret.a[ k + 1 ] += ret.a[ k ] / MAX ;
                    ret.a[ k ] %= MAX ;
                    ret.m = max( ret.m , k + 1 ) ;
                }
            }
        }
        return ret ;
    }
     
    int main(  ) {
        scanf( "%d%d" , &n , &m ) ;
        ans.Transform( 1 ) ;
        for ( int i = 0 ; i ++ < n ; ) {
            rec.Transform( i ) ;
            ans = Multiply( ans , rec ) ;
        }
        rec.Transform( n + 1 ) ;
        ans = Multiply( ans , rec ) ;
        for ( int i = n - m + 4 ; i <= n + 2 ; i ++ ) {
            rec.Transform( i ) ;
            ans = Multiply( ans , rec ) ;
        }
        rec.Transform( ( n + 3 ) * n + 2 * m ) ;
        ans = Multiply( ans , rec ) ;
        ans.Print(  ) ;
        return 0 ;
    }
    

    相关文章

      网友评论

        本文标题:BZOJ-2729: [HNOI2012]排队(排列组合+高精度

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