卢卡斯定理

遇到好多次了,,,但总是写不出来。

来练几个最基础的题吧:http://acm.hdu.edu.cn/showproblem.php?pid=3037

                                   http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1118

卢卡斯定理的基本应用:基本的组合数学,C(N+M,M)%P

卢卡斯定理模板:(hdu3037)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>

using namespace std;

typedef long long LL;
#define M 1e9 + 7

typedef struct Node
{
    LL exp_mod(LL a, LL b, LL p)
    {
        LL res = 1;
        while(b != 0)
        {
            if(b&1) res = (res * a) % p;
            a = (a*a) % p;
            b >>= 1;
        }
        return res;
    }
    LL Comb(LL a, LL b, LL p)
    {
        if(a < b)   return 0;
        if(a == b)  return 1;
        if(b > a - b)   b = a - b;

        LL ans = 1, ca = 1, cb = 1;
        for(LL i = 0; i < b; ++i)
        {
            ca = (ca * (a - i))%p;
            cb = (cb * (b - i))%p;
        }
        ans = (ca*exp_mod(cb, p - 2, p)) % p;
        return ans;
    }
    LL lucas(int n, int m, int p)
    {
        LL ans = 1;
        while(n&&m&&ans)
        {
            ans = (ans*Comb(n%p, m%p, p)) % p;
            n /= p;
            m /= p;
        }
        return ans;
    }
} Lucas;
int main()
{
    int t;
    Lucas Lu;
    scanf("%d",&t);
    while(t --)
    {
        int n,m,p;
        scanf("%d%d%d",&n,&m,&p);
        printf("%lld\n",Lu.lucas(n+m,m,p));
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值