• HDU 4390 Number Sequence [容斥原理]


      求把一个数拆成N个非1的数相乘的方案数有多少种(顺序不一样的算不一样的)。

      如果不考虑是否为1的方案数,对原数所有的质因数直接用插板法然后乘起来就可以了,麻烦的是有一个所有数都不能为1的问题,这里可以用容斥原理组成。用f(i)表示有i~N个1的方案数,用x[i]表示确切有i个0的方案数。我们可以得到如下方程组:

    f(0)=1x[0]+1x[1]+1x[2]+1x[3]+....;

    f(1)=          1x[1]+2x[2]+3x[3]+....;

    f(2)=                    1x[1]+3x[3]+...;

    f(3)=                              1x[3]+...;

      比如在算f(1)的时候,假设有3位数,我们枚举每一位为1,会产生重复的情况,这个稍微推一下就知道了。

      所以最后的x[0]=f(0)-f(1)+f(2)-f(3)....

      

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 #define MAXN 1000005
     5 #define MAXC 110
     6 #define MOD 1000000007
     7 typedef long long LL;
     8 int n,b[22],maxs;
     9 int cc[MAXC][MAXC];
    10 int tot[MAXN],pri[MAXN],pris;
    11 void init(){
    12     memset(pri,0,sizeof pri),pri[1]=1;
    13     for(int i=1;i<MAXN;i++){
    14         if(pri[i])continue;
    15         for(int j=i*2;j<MAXN;j+=i)pri[j]=1;
    16     }
    17     pris=0;
    18     for(int i=2;i<MAXN;i++)
    19         if(!pri[i])pri[pris++]=i;
    20     for(int i=0;i<MAXC;cc[i++][0]=1)
    21         for(int j=1;j<=i;j++)
    22             cc[i][j]=((LL)cc[i-1][j-1]+cc[i-1][j])%MOD;
    23 }
    24 int main(){
    25     //freopen("test.in","r",stdin);
    26     init();
    27     while(scanf("%d",&n)!=EOF){
    28         memset(tot,0,sizeof tot),maxs=0;
    29         for(int i=1;i<=n;i++){
    30             scanf("%d",&b[i]);
    31             for(int j=0;j<pris&&pri[j]<=b[i];j++){
    32                 while(b[i]%pri[j]==0){
    33                     tot[j]++,b[i]/=pri[j];
    34                     maxs=std::max(maxs,j+1);
    35                 }
    36             }
    37         }
    38         LL ans=0,tmp;
    39         //容斥原理
    40         for(int i=0;i<n;i++){
    41             tmp=cc[n][i];
    42             for(int j=0;j<maxs;j++)
    43                 tmp=tmp*cc[n-i-1+tot[j]][n-i-1]%MOD;
    44             ans+=(i&1)?-tmp:tmp;
    45             ans%=MOD;
    46         }
    47         printf("%I64d\n",(ans%MOD+MOD)%MOD);
    48     }
    49     return 0;
    50 }
  • 相关阅读:
    JavaScript Date对象
    BOM 和 DOM
    JS变量声明方式
    CSS3 选择器
    Python文件操作
    第十三章 迭代器、生成器、 装饰器
    python专题 --- 递归
    React JSX
    ES6——面向对象应用
    ES6——面向对象-基础
  • 原文地址:https://www.cnblogs.com/swm8023/p/2698766.html
Copyright © 2020-2023  润新知