HIT2813 Garden visiting【组合数】

题目链接:

http://acm-hit.sunner.cn/judge/show.php?Proid=2813


题目大意:

给你三个整数 N、M、P,求组合数 C(N+M-2,M-1) % P。


解题思路:

将阶乘表示为大整数分解的形式,将各个素因子按素因子的幂相乘起来就是所求

答案(记得要对 P 取余)。


AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define LL long long
using namespace std;

const int MAXN = 200000;
bool Prime[MAXN+10];
int Primer[MAXN+10];

int GetPrime()
{
    for(int i = 2; i <= MAXN; ++i)
        Prime[i] = true;

    for(int i = 2; i <= MAXN; ++i)
    {
        if(Prime[i])
            for(int j = i+i; j <= MAXN; j+=i)
                Prime[j] = false;
    }

    int num = 0;
    for(int i = 2; i <= MAXN; ++i)
        if(Prime[i])
            Primer[num++] = i;
    return num;
}

int PowMod(LL a,LL b,LL mo)
{
    LL ret = 1;
    while(b)
    {
        if(b & 1)
            ret = ret * a % mo;
        a = a * a % mo;
        b >>= 1;
    }
    return ret;
}

int Cal(int n,int p)
{
    int sum = 0;
    while(n)
    {
        n /= p;
        sum += n;
    }
    return sum;
}

int main()
{
    int T,N,M,Mod;
    int num = GetPrime();
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&N,&M,&Mod);
        N += M-2;
        M--;

        LL ans = 1;
        for(int i = 0; i < num && Primer[i] <= N; ++i)
        {
            int temp = Cal(N,Primer[i]) - Cal(M,Primer[i]) - Cal(N-M,Primer[i]);
            ans = ans * PowMod(Primer[i],temp,Mod) % Mod;
        }
        printf("%lld\n",ans);
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值