• HDU 4390 Number Sequence (容斥原理+组合计数)


    HDU 4390

    题意:

    大概就是这样。不翻译了:
    Given a number sequence b1,b2bn.
    Please count how many number sequences a1,a2,...,ansatisfy the condition thata1a2...an=b1b2bn(ai,bi>1).

    思路:

    我们能够确定一件事:等号两边由同样数量的质因子组成。

    假设ai能够等于1,答案就是把这些质因子分配进n个位置的方案数。
    设左边的数字共由x个质因子组成,当中第i个质因子出现mi次。
    把m个同样小球放进n个不同盒子(盒子能够为空)中的方案数是 Cn1m+n1
    那么把mi个同样质因子放进n个不同位置上的方案数是 Cn1mi+n1。最后答案就是xi=1Cn1mi+n1.

    但这并非我们想要的答案。由于我们不同意某个位置为空(即存在ai=1),所以我们要减去一些某些位置为空的方案。
    由于至少有一个位置为空与至少有两个位置为空存在反复情况等。减的方法是容斥原理。
    ans=xi=1Cn1mi+n1C1nxi=1Cn2mi+n2+C2nxi=1Cn3mi+n3...Cn1nxi=1C0mi.
    (答案 = 全部可能 - 一个为空 + 两个为空 - 三个为空 +…)

    代码:

    /*
    * @author FreeWifi_novicer
    * language : C++/C
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<string>
    #include<map>
    #include<set>
    #include<vector>
    #include<queue>
    
    using namespace std;
    
    #define clr( x , y ) memset(x,y,sizeof(x))
    #define cls( x ) memset(x,0,sizeof(x))
    #define mp make_pair
    #define pb push_back
    typedef long long lint;
    typedef long long ll;
    typedef long long LL;
    
    const int maxn = 1005 ;
    const int mod = 1e9 + 7 ;
    lint C[505][505];
    lint b[25] ;
    map<int , int>m ;
    
    int n ;
    void init(){
        cls( C ) ;
        C[0][0] = 1 ;
        for( int i = 1 ; i <= 500 ; i++ ){
            C[i][0] = 1 ;
            for( int j = 1 ; j <= i ; j++ ){
                C[i][j] = C[i-1][j] + C[i-1][j-1] ;
                if( C[i][j] > mod ) C[i][j] -= mod ;
            }
        }
    }
    
    lint work(){
        for( int i = 1 ; i <= n ; i++ ){
            for( int j = 2 ; j * j <= b[i] ; j++ ){
                while( b[i] % j == 0 ) {
                    m[j] ++ ;
                    b[i] /= j ;
                }
            }
            if( b[i] > 1 ) m[b[i]] ++ ;
        }
        map<int,int>::iterator it ;
    
        lint ans = 1 ;
        for( it = m.begin() ; it != m.end() ; it++ ){
            int num = it->second ;
            ans = ( ans * C[ num + n - 1 ][ n - 1 ] ) % mod ;
        }
        for( int i = 1 ; i < n ; i++ ){
            lint val = C[n][i] ;
            for( it = m.begin() ; it != m.end() ; it++ ){
                int num = it->second ;
                val = ( val * C[ num + n - i - 1 ][ n - i - 1 ] ) % mod ;
            }
            if( i & 1 )
                ans = ( ans - val + mod ) % mod ;
            else
                ans = ( ans + val ) % mod ;
        }
        return ans ;
    
    }
    int main(){
    //  freopen("input.txt","r",stdin);
        init() ;
        while( cin >> n ){
            m.clear();
            for( int i = 1 ; i <= n ; i++ )
                cin >> b[i] ;
           cout << work() << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    组件定义
    序列化代码
    Views 代码 导包
    DRF 初始化
    Urls 代码
    怎么用sublime text 3搭建python 的ide
    C语言位运算
    ZOJ 1104 Leaps Tall Buildings
    UVa 10739 String to Palindrome
    ZOJ 3563 Alice's Sequence II
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/8453105.html
Copyright © 2020-2023  润新知