lucas 定理学习

大致意思就是求组合数C(n , m) % p的值, p为一个偶数

可以将组合数的n 和 m都理解为 p 进制的表示

n  = ak*p^k + a(k-1)*p^(k-1) + ... + a1*p + a0

m = bk*p^k + b(k-1)*p^(k-1) + ... + b1*p + b0

然后C(n,m)%p = C(ak , bk) * C(a(k-1) , b(k-1)) * ... * C(a1 , b1) * C(a0 , b0) % p

当然这其中出现 ai < bi的情况那直接视为乘以了 0

其他情况都是正常的组合数计算

因为p为素数,取模的过程求逆元就是利用欧拉定理来求解

a^(-1) = a^(p-2) (mod p)

那么只要快速幂求a^(p-2) % p的值就行了 , 那么组合数C(ai , bi) 就可以算出来了

HDU 4349 求C(n , i)中 0<=i<=n 中多少个可以使C(n , i)为奇数

这里先将n转化为二进制表示,因为C(n,m)%p = C(ak , bk) * C(a(k-1) , b(k-1)) * ... * C(a1 , b1) * C(a0 , b0) % p

那么只会出现ai = 0 , 1 bi = 0 , 1的情况

那么只有ai=0 , bi = 1 才是C(ai , bi) = 0为偶数,其他时候都是奇数,那只要枚举每一位保证那一位出现的数字可能不超过n对应的二进制位即可

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 int main() {
 5     int n;
 6     while(~scanf("%d" , &n)){
 7         int ret = 1;
 8         while(n){
 9             ret = ret*((n&1)+1);
10             n>>=1;
11         }
12         printf("%d\n",ret);
13     }
14     return 0;
15 }

HDU 3037 一道比较裸的lucas定理的题目

求C(n+m , n)%p的值

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4
 5 int q_pow(int a , int b , int p)
 6 {
 7     ll ret = 1;
 8     while(b){
 9         if(b&1) ret = ret*a%p;
10         a = (ll)a*a%p;
11         b>>=1;
12     }
13     return ret;
14 }
15
16 int C(int a , int b , int p)
17 {
18     if(b==0) return 1;
19     if(a<b) return 0;
20     if(a==b) return 1;
21     int s=1 , t=1;
22     for(int i=1 ; i<=b ; i++) s=(ll)s*(a-i+1)%p;
23     for(int i=1 ; i<=b ; i++) t=(ll)t*i%p;
24     //cout<<"C: "<<a<<" "<<b<<" "<<p<<" "<<s<<" "<<t<<endl;
25     return (ll)s*q_pow(t , p-2 , p)%p;
26 }
27
28 int lucas(int a, int b,int p)
29 {
30     //cout<<"in: "<<a<<" "<<b<<" "<<p<<endl;
31     if(b==0) return 1;
32     if(a<b) return 0;
33     if(a==b) return 1;
34     //cout<<"en: "<<C(a%p , b%p , p)<<endl;
35     return (ll)C(a%p , b%p , p)*lucas(a/p , b/p , p)%p;
36 }
37
38 int main() {
39     //freopen("in.txt" , "r" , stdin);
40     int n;
41     scanf("%d" , &n);
42     while(n--){
43         int a , b , p;
44         scanf("%d%d%d", &a , &b , &p);
45         printf("%d\n" , lucas(a+b,a,p));
46     }
47     return 0;
48 }
时间: 2024-10-22 09:52:03

lucas 定理学习的相关文章

Lucas定理学习(进阶中)

(1)Lucas定理:p为素数,则有: (2)证明: n=(ak...a2,a1,a0)p = (ak...a2,a1)p*p + a0 =  [n/p]*p+a0,m=[m/p]*p+b0其次,我们知道,对任意质数p有(1+x)^p=1+(x^p)(mod p) .我们只要证明这个式子:C(n,m)=C([n/p],[m/p]) * C(a0,b0)(mod p),那么就可以用归纳法证明整个定理.对于模p而言,我们有下面的式子成立: 上式左右两边的x的某项x^m(m<=n)的系数对模p同余.其

【学习总结】数学-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

Lucas定理--大组合数取模 学习笔记

维基百科:https://en.wikipedia.org/wiki/Lucas%27_theorem?setlang=zh 参考:http://blog.csdn.net/pi9nc/article/details/9615359 http://hi.baidu.com/lq731371663/item/d7261b0b26e974faa010340f http://hi.baidu.com/j_mat/item/8e3a891c258c4fe9dceecaba 综合以上参考,我做的一下总结:

[Lucas定理]【学习笔记】

这种神奇的东西............... 参考资料:http://www.cnblogs.com/jianglangcaijin/p/3446839.html Lucas定理 适用于n很大p较小的时候 $ C_n^m\%p \ p \ is \ prime$ $ n=n_k*p^k+n_{k-1}*p^{k-1}+...+n_2*p^2+n_1*p+n_0 $ $ m=m_k*p^k+m_{k-1}*p^{k-1}+...+m_2*p^2+m_1*p+m_0 $ $ C_n^m=\prod\

【日常学习】【组合数取模Lucas定理】HDU3037 Saving Beans题解

[提前声明:此题没有通过!WA!有待进一步研究修改.放在这里只是起一个例子的作用,其实这道题鄙人并没有真正掌握= =]. [本文努力抄袭模仿了小花妹妹的博文0戳我0)] 题目大意:共T个测试点,每个测试点中,给定n.m,求将不超过m个种子放入n个坑的方案总数,最后答案对质数p取模.(一共m个,每个坑放多少无所谓,最后没放完m个也无所谓) 数据范围:1 <= n, m <= 1000000000, 1 < p < 100000. 思路:原题意即求方程x1+-+xn=m解的个数,因为中

学习:Lucas定理

模板题 Lucas定理 在数论中,Lucas定理用于计算二项式系数\({\tbinom {m}{n}}\)被质数\(p\)除的所得的余数. 描述 设\(p\)为素数,\(a,b\in N_+\),且 \[a=a_kp^k+a_{k-1}p^{k-1}+\cdots+a_1p+a_0\] \[b=b_kp^k+b_{k-1}p^{k-1}+\cdots+b_1p+b_0\] 这里\(0\leq a_i,b_i\leq p-1\bigwedge a_i,b_i\in Z(i=0,1,2,3,\cdo

BZOJ 4403 2982 Lucas定理模板

思路: Lucas定理的模板题.. 4403 //By SiriusRen #include <cstdio> using namespace std; const int mod=1000003; #define int long long int cases,N,L,R,fac[mod],inv[mod]; int C(int n,int m){ if(n<m)return 0; if(n<mod&&m<mod)return fac[n]*inv[n-m]

HDU 3037 Saving Beans (数论,Lucas定理)

题意:问用不超过 m 颗种子放到 n 棵树中,有多少种方法. 析:题意可以转化为 x1 + x2 + .. + xn = m,有多少种解,然后运用组合的知识就能得到答案就是 C(n+m, m). 然后就求这个值,直接求肯定不好求,所以我们可以运用Lucas定理,来分解这个组合数,也就是Lucas(n,m,p)=C(n%p,m%p)* Lucas(n/p,m/p,p). 然后再根据费马小定理就能做了. 代码如下: 第一种: #pragma comment(linker, "/STACK:10240

HDU3037 Saving Beans(Lucas定理+乘法逆元)

题目大概问小于等于m个的物品放到n个地方有几种方法. 即解这个n元一次方程的非负整数解的个数$x_1+x_2+x_3+\dots+x_n=y$,其中0<=y<=m. 这个方程的非负整数解个数是个经典问题,可以+1转化正整数解的个数用插板法解决:$C_{y+n-1}^{n-1}=C_{y+n-1}^y$. 而0<=y<=m,最后的结果就是—— $$\sum_{i=0}^m C_{i+n-1}^i$$ $$C_{n-1}^0+C_{n}^1+C_{n+1}^2+\dots+C_{n-1