Lucas

卢卡斯定理自我感觉感性理解比堆式子更能然人静下心来看

我的大部分式子都是展开形式就是一堆没有的展开

首先我们需要证明\(C_p^i=\frac{p}{j}C_{p-1}^{i-1}\equiv0~~~(mod~p),(1<=i<=p-1)\)

\(C_p^i=\frac{p!}{i!(p-i)!}=\frac{p}{i} \frac{(p-1)!}{(i-1)!(p-1-i+1)!}= \frac{p}{i} \frac{(p-1)!}{(i-1)!(p-i)!}=\frac{p}{j}C_{p-1}^{i-1}\)

得证。

然后根据这种性质和二项式定理。,我们马上得出鬼嘞!!

\((1+x)^p=C_p^01^p+C_p^1x^{2}+....+C_p^px^p=C_p^01^px^0+C_p^p1^0x^p=1+x^p\)

然后我们接下来要求证

\(C_a^b=C_{a_0}^{b_0}\cdot C_{a_1p}^{b_1p} \cdot C_{a_2p^2}^{b_2p^2}.....\)

其实我们令\(a=lp+r,b=sp+j\)好奇怪的变量名呀
求证\(C_a^b=C_{lp}^{sp}\cdot C_{r}^{j}\)然后利用性质递归求解就可以了。

继续从二次项定理出发

\((1+x)^a=(1+x)^{lp} \cdot (1+x)^r\)

然后展开\((1+x)^{lp}\)

\((1+x)^{lp} \equiv ((1+x)^p)^l \equiv (1+x^p)^l\)

\(\therefore (1+x)^a \equiv (1+x^p)^l \cdot (1+x)^r\)

观察项\(x^b\)的系数

\(\because C_a^bx^b \equiv C_l^sx^{sp} \cdot C_r^jx^j\)

\(\therefore C_a^bx^b \equiv C_l^s \cdot C_r^jx^b\)

\(\therefore C_a^b\equiv C_l^s\cdot C_r^j \equiv C_{\lfloor \frac{a}{p} \rfloor}^{\lfloor \frac{b}{p} \rfloor}\cdot C_{a~mod~p}^{b~mod~p}\)

上面的下取整是计算l and s,mod 是为了计算 r and j

得证

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
long long base[101000],mod;
long long kasumi(long long n,long long m)//利用费马小定理求解逆元
{
	long long res=1;
	while(m)
	{
		if(m&1)	res=(res*n)%mod;
		m>>=1;
		n=(n*n)%mod;
	}
	return res;
}
long long C(long long n,long long m)
{
	if(n<m)	return 0;
	int res=(base[n]*kasumi(base[m],mod-2)*kasumi(base[n-m],mod-2))%mod;
	return res;
}
long long lucas(long long n,long long m)
{
	if(n<m)	return 0;
	if(!n)	return 1;
	return (lucas(n/mod,m/mod)*C(n%mod,m%mod))%mod;
}
int main()
{
	base[0]=1;
	long long n,m;
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%lld%lld%lld",&n,&m,&mod);
		for(int i=1;i<=n+m;i++)
			base[i]=(base[i-1]*i)%mod;
		printf("%lld\n",lucas(n+m,m));	
	}
}
posted @ 2018-07-07 22:39  Lance1ot  阅读(135)  评论(0编辑  收藏  举报