zoukankan      html  css  js  c++  java
  • [组合数取模] 方法汇总

    1.利用整数唯一分解定理,求(n+1-m) * (n+m)!  /  ( m! * (n+1)!  )

    不论什么正整数都有且仅仅有一种方法写出其素因子幂相乘的形式。比方18= 2 * 3^2

    A=(p1^k1)*(p2^k2)*(p3^k3)*(p4^k4)*......*(pn^kn)   pi为素数

    还有把阶层看作一个数,比m! 如何求m!里面素数2的指数呢?

    cnt=0;   while(m)  {  m/=2; cnt+=m; }  就能够了,为什么呢?考虑m=4,则m!=  4*3*2*1, 第一次m/=2。是计算m!里面有多少个数能整除2的(有4,2),所以cnt+=2,有两个数贡献

    了两个素数2,接下来第二次m/=2。是计算m!里面有多少个数能整除4的,有1个数又贡献了一个素数2.

    所以先预先筛出最大范围内的素数,然后考虑每一个素数就好了,关键是求出整个式子的该素数的指数是多少。

    模板:

    bool isprime[maxn*2+10];
    int prime[maxn*2+10];
    int len=0;//素数的个数
    int n,m;
    void sieve(int n)//筛n以内的素数
    {
        for(int i=0;i<=n;i++)
            isprime[i]=1;
        isprime[0]=isprime[1]=0;
        for(int i=2;i<=n;i++)
            if(isprime[i])
            {
                prime[len++]=i;
                for(int j=2*i;j<=n;j+=i)
                    isprime[j]=0;
            }
    }
    int cal(int p,int n)//计算n!里面有多少个p相乘
    {
        int ans=0;
        while(n)
        {
            n/=p;
            ans+=n;
        }
        return ans;
    }
    
    int main()
    {
            sieve(maxn*2);
            long long ans=1;//记得要用long long
            cin>>n>>m;
            int nm=n+1-m;
            for(int i=0;i<len&&prime[i]<=(n+m);i++)//prime[i]<=(n+m)是由于拆成素数幂相乘的形式该素数不会大于n+m,最大(n+m)!   (n+m)*(n+m-1)*(n+m-2).....
            {
                int cnt=0;//分解为素数prime[i]的指数是多少
                while(nm%prime[i]==0)//nm中有多少个prime[i],也就是把nm分解后prime[i]的指数
                {
                    nm/=prime[i];
                    cnt++;
                }
                cnt=cnt+cal(prime[i],n+m)-cal(prime[i],m)-cal(prime[i],n+1);//加上分子的指数再减去分母的指数
                for(int j=1;j<=cnt;j++)
                {
                    ans=ans*prime[i];
                    if(ans>=mod)
                        ans%=mod;
                }
            }
            cout<<ans<<endl;
            return 0;
    }
    


     

     

  • 相关阅读:
    JSP 服务器响应
    JSP 客户端请求
    杂烩笔记
    ExtJS panel
    DB2存储过程语法规则
    CentOS查看软件源提供的软件版本命令
    Linux查看程序端口占用情况【转】
    359. Logger Rate Limiter
    358. Rearrange String k Distance Apart
    357. Count Numbers with Unique Digits
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5325473.html
Copyright © 2011-2022 走看看