LightOJ - 1067 (卢卡斯定理,打表法)

本文介绍了一种使用卢卡斯定理计算组合数C(m,n)%p的方法,适用于大范围的n(1≤n≤10^6)和k(0≤k≤n),并提供了一个具体的C++实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:求C(m,n)%p;

题解:因为n (1 ≤ n ≤ 106), k (0 ≤ k ≤ n).T (≤ 2000)所以用到卢卡斯定理。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <numeric>
#include <cctype>
using namespace std;
#define LL __int64
#define N 1000100
#define M 1000000007ll
LL fac[N];

void init(LL p)
{
    LL i;
    fac[0] =1;
    for(i =1; i <= p; i++)
        fac[i] = fac[i-1]*i % p;
}

LL exp_mod(LL a, LL b, LL p)
{
    LL tmp = a % p, ans =1;
    while(b)
    {
        if(b & 1)  ans = ans * tmp % p;
        tmp = tmp*tmp % p;
        b >>=1;
    }
    return  ans;
}

LL C(LL n, LL m, LL p)
{
    if(m > n)
    	return 0;
    return  fac[n]*exp_mod(fac[m]*fac[n-m], p-2, p) % p;//逆元
}

LL Lucas(LL n, LL m, LL p)
{
    if(m ==0)
    	return 1;
    return  (C(n%p, m%p, p)*Lucas(n/p, m/p, p))%p;
}


int main()
{
	int T;
	LL n,m,p,cas=1;
	p=1000003;
	init(p);
	
	scanf("%d",&T);
	while(T--)
	{
		scanf("%lld %lld",&n,&m);
		printf("Case %lld: %lld\n",cas++,Lucas(n,m,p));
	}
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值