洛谷 P3807 【模板】卢卡斯定理

洛谷 P3807 【模板】卢卡斯定理

洛谷传送门

题目背景

这是一道模板题。

题目描述

给定整数 n, m, pn,m,p 的值,求出 C_{n + m}^n \bmod pC**n+m**nmodp 的值。

输入数据保证 pp 为质数。

注: CC 表示组合数。

输入格式

本题有多组数据

第一行一个整数 TT,表示数据组数。

对于每组数据:

一行,三个整数 n, m, pn,m,p

输出格式

对于每组数据,输出一行,一个整数,表示所求的值。


题解:

有关卢卡斯定理:

卢卡斯定理

实现的时候只需要注意递归边界的处理。

首先,发现如果n<m,那么就是0.

然后那么n小于模数,那么直接上去就算(阶乘+逆元)。

剩下的递归求解就好了。

代码:

#include<cstdio>
#define int long long
using namespace std;
int n,m,p;
const int maxn=2e5+5;
int fac[maxn];
int inv[maxn];
int lucas(int x,int y)
{	
	if(x<y)
		return 0;
	else if(x<p)
		return fac[x]*inv[y]*inv[x-y]%p;
	else 
		return lucas(x%p,y%p)*lucas(x/p,y/p)%p;
}
signed main()
{
	int t;
	scanf("%lld",&t);
	fac[0]=1;
	fac[1]=1;
	inv[1]=1;
	inv[0]=1;
	while(t--)
	{
		scanf("%lld%lld%lld",&n,&m,&p);
		for(int i=2;i<=n+m;i++)
			fac[i]=fac[i-1]*i%p;
		for(int i=2;i<=n+m;i++)
			inv[i]=(p-p/i)*inv[p%i]%p;
		for(int i=2;i<=n+m;i++)
			inv[i]=inv[i-1]*inv[i]%p;
		printf("%lld\n",lucas(n+m,m));
	}
	return 0;
}
posted @ 2020-12-04 11:13  Seaway-Fu  阅读(147)  评论(0编辑  收藏  举报