zoukankan      html  css  js  c++  java
  • HDU 4390 Number Sequence 容斥原理

    Number Sequence

    Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

    Problem Description
    Given a number sequence b1,b2…bn. Please count how many number sequences a1,a2,...,an satisfy the condition that a1*a2*...*an=b1*b2*…*bn (ai>1).
     
    Input
    The input consists of multiple test cases. For each test case, the first line contains an integer n(1<=n<=20). The second line contains n integers which indicate b1, b2,...,bn(1<bi<=1000000, b1*b2*…*bn<=1025).
     
    Output
    For each test case, please print the answer module 1e9 + 7.
     
    Sample Input
    2 3 4
     
    Sample Output
    4
    Hint
    For the sample input, P=3*4=12. Here are the number sequences that satisfy the condition:
    2 6
    3 4
    4 3
    6 2
     
    Source
     
     

    将每一个数分解质因数,得到每个质因数出现的次数(和质数本身没有关系),然后就要用到容斥原理了,

    也就是将每个质数出现的次数放到n个容器中去,这里要注意下1的情况也就是某个容器里面没有放数。

    这样结果=总的方案数-有一个容器没放数+有2个容器没有放数……

    将m个数放入n个容器的方法数有C(n+m-1,n-1) 。

    #include <iostream>
    #include <stdio.h>
    #include <queue>
    #include <stdio.h>
    #include <string.h>
    #include <vector>
    #include <queue>
    #include <set>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <math.h>
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std ;
    typedef long long LL ;
    const int M_P=1008 ;
    const LL Mod=1000000007 ;
    bool isprime[M_P+8] ;
    int prime[M_P] ,id;
    map<int ,int>my_hash ;
    map<int ,int>::iterator p ;
    void make_prime(){
        id=0 ;
        memset(isprime,0,sizeof(isprime)) ;
        for(int i=2;i<=M_P;i++){
            if(!isprime[i])
                 prime[++id]=i ;
            for(int j=1 ;j<=id&&i*prime[j]<=M_P;j++){
                 isprime[i*prime[j]]=1 ;
                 if(i%prime[j]==0)
                      break  ;
            }
        }
    }
    LL C[258][258] ;
    void get_C(){
        C[1][0]=C[1][1]=1 ;
        for(int i=2;i<=250;i++){
             C[i][0]=C[i][i]=1 ;
             for(int j=1;j<i;j++){
                C[i][j]=C[i-1][j-1]+C[i-1][j] ;
                if(C[i][j]>=Mod)
                    C[i][j]%=Mod ;
             }
        }
    }
    void gao(int N){
       for(int i=1;i<=id&&prime[i]*prime[i]<=N;i++){
           if(N%prime[i]==0){
              while(N%prime[i]==0){
                    my_hash[prime[i]]++ ;
                    N/=prime[i] ;
              }
           }
           if(N==1)
               break  ;
       }
       if(N!=1)
           my_hash[N]++ ;
    }
    vector<int>vec ;
    int N ;
    LL Sum(){
        LL ans=1 ;
        for(int k=0;k<vec.size();k++){
            ans*=C[vec[k]+N-1][N-1] ;
            if(ans>=Mod)
                ans%=Mod ;
        }
        for(int i=1;i<=N;i++){
            LL sum=C[N][i] ;
            for(int k=0;k<vec.size();k++){
                int m=N-i ;
                sum*=C[vec[k]+m-1][m-1] ;
                if(sum>=Mod)
                    sum%=Mod  ;
            }
            if(i&1)
                ans-=sum  ;
            else
                ans+=sum  ;
            ans=(ans%Mod+Mod)%Mod ;
        }
        return ans ;
    }
    int main(){
       make_prime() ;
       get_C() ;
       int M  ;
       while(scanf("%d",&N)!=EOF){
           my_hash.clear() ;
           vec.clear() ;
           for(int i=1;i<=N;i++){
                scanf("%d",&M) ;
                gao(M) ;
           }
           for(p=my_hash.begin();p!=my_hash.end();p++)
               vec.push_back(p->second) ;
           cout<<Sum()<<endl;
       }
       return 0 ;
    }
  • 相关阅读:
    枚举 + 进制转换 --- hdu 4937 Lucky Number
    扫描线 + 线段树 : 求矩形面积的并 ---- hnu : 12884 Area Coverage
    暴力枚举 + 24点 --- hnu : Cracking the Safe
    dp or 贪心 --- hdu : Road Trip
    数论
    模拟 --- hdu 12878 : Fun With Fractions
    图论 --- spfa + 链式向前星 : 判断是否存在正权回路 poj 1860 : Currency Exchange
    图论 --- spfa + 链式向前星 (模板题) dlut 1218 : 奇奇与变形金刚
    图论 --- 最小生成树 + 剪枝 + 路径合并
    图论 ---- spfa + 链式向前星 ---- poj 3268 : Silver Cow Party
  • 原文地址:https://www.cnblogs.com/liyangtianmen/p/3385066.html
Copyright © 2011-2022 走看看