首页 > 代码库 > 【学习总结】数学-lucas定理
【学习总结】数学-lucas定理
定义:
数论Lucas定理是用来求 C(mn)%p的值,p是素数.
描述:
lucas(n,m,p)=lucas(n/p,m/p,p)?C(m%pn%p)
lucas(n,0,p)=1
证明:
设p为素数,A,B为正整数,并且有(即A,B的p进制情况):
A=akpk+ak?1pk?1+…+a1p1+a0
B=bkpk+bk?1pk?1+…+b1p1+b0因为C(jp)=C(j?1p?1)?pj=0 (含有因子p)
所以(1+x)t(modp)=(1+xt)(modp) (中间展开项均含有C(ip))于是乎,我们让t=A
(1+x)A=(1+x)akpk+ak?1pk?1+…+a1p1+a0(modp)
=(1+x)akpk?(1+x)ak?1pk?1?…?(1+x)a0(modp)
=(1+xpk)ak?(1+xpk?1)ak?1?…?(1+x)a0(modp)
对比两边xb的系数,根据多项式定理和p进制数的性质(A对应的p进制,导致了系数的确定)
C(BA)=C(bkak)?C(bk?1ak?1)?…?C(b0a0)
代码:
typedef long long ll;
ll n, m, p;
ll qPow (ll a, ll k) {
ll ans = 1;
while (k) {
if (k&1)
ans = (ans * a) % p;
a = (a * a) % p;
k /= 2;
}
return ans;
}
ll C (ll a, ll b, ll p) {
if (a < b)
return 0;
if (b > a - b)
b = a - b;
ll up = 1, down = 1;
for (ll i = 0; i < b; i++) {
up = up * (a-i) % p;
down = down * (i+1) % p;
}
return up * qPow(down, p-2) % p; // 逆元
}
ll lucas (ll a, ll b, ll p) {
if (b == 0)
return 1;
return C(a%p, b%p, p) * lucas(a/p, b/p, p) % p;
}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。