[Luogu 3807]【模板】卢卡斯定理
2017-10-07 21:08
351 查看
Description
给定n,m,p(1≤n,m,p≤10^5)求 C_{n+m}^{m} \mod p
保证P为prime
C表示组合数。
一个测试点内包含多组数据。
Input
第一行一个整数T(T≤10),表示数据组数第二行开始共T行,每行三个数n m p,意义如上
Output
共T行,每行一个整数表示答案。Sample Input
2 1 2 5 2 1 5
Sample Output
3 3
题解
$Lucas$定理。就是$C^m _n \mod p = C^{m/p} _{n/p}*C^{m \mod p} _{n \mod p} \mod p$。
证明:不会。记着就行。
代码实现方面,注意两点:
1.对于$C^{m/p} _{n/p}$部分可以继续使用$Lucas$定理递归求解。
2.求逆元,可以用费马小定理做快速幂,当然也可以线性预处理阶乘逆元。注意,若线性预处理,需要将$0$位赋为$1$(很好理解,不做解释)。
//It is made by Awson on 2017.10.7 #include <map> #include <set> #include <cmath> #include <ctime> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <string> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define LL long long #define Max(a, b) ((a) > (b) ? (a) : (b)) #define Min(a, b) ((a) < (b) ? (a) : (b)) using namespace std; const int N = 1e5; int n, m, p; int A[N+5], B[N+5]; int C(int n, int m, int p) { if (m > n) return 0; return (LL)A *B[n-m]%p*B[m]%p; } int Lucas(int n, int m, int p) { if (!m) return 1; return (LL)C(n%p, m%p, p)*Lucas(n/p, m/p, p)%p; } void work() { scanf("%d%d%d", &n, &m, &p); A[0] = B[0] = A[1] = B[1] = 1; n += m; for (int i = 2; i <= p; i++) B[i] = -(LL)(p/i)*B[p%i]%p; for (int i = 2; i <= p; i++) A[i] = (LL)A[i-1]*i%p, B[i] = (LL)B[i-1]*B[i]%p; printf("%d\n", (Lucas(n, m, p)+p)%p); } int main() { int t; scanf("%d", &t); while (t--) work(); return 0; }
相关文章推荐
- 【洛谷】3807 【模板】卢卡斯定理
- 洛谷.3807.[模板]卢卡斯定理(Lucas)
- [模板] 卢卡斯定理
- Luogu 3807(Lucas定理)
- 组合数模板+ 卢卡斯定理
- 洛谷 P3807 【模板】卢卡斯定理
- 洛谷—— P3807 【模板】卢卡斯定理
- 【Luogu3807】【模板】卢卡斯定理(数论)
- 卢卡斯定理的模板以及应用
- 组合数取模(卢卡斯定理、模板)
- [模板]-卢卡斯(Lucas)定理
- 卢卡斯定理模板(当n和m很大,p为素数时)
- 洛谷P3807 【模板】卢卡斯定理exgcd
- 【模板】卢卡斯定理
- luogu P3807 【模板】卢卡斯定理
- Unknown Treasure ————(hdu5446) 中国剩余定理+卢卡斯定理
- 【luogu3374】模板 树状数组 1
- BZOJ4591 SHOI2015超能粒子炮·改(卢卡斯定理+数位dp)
- poj 1006中国剩余定理(模板题)
- 【XSY2691】中关村 卢卡斯定理 数位DP