Lightoj 1067(逆元)
来源:互联网 发布:c语言二分法求方程的根 编辑:程序博客网 时间:2024/05/05 11:24
Given n different objects, you want to take k of them. How many ways to can do it?
For example, say there are 4 items; you want to take 2 of them. So, you can do it 6 ways.
Take 1, 2
Take 1, 3
Take 1, 4
Take 2, 3
Take 2, 4
Take 3, 4
Input
Input starts with an integer T (≤ 2000), denoting the number of test cases.
Each test case contains two integers n (1 ≤ n ≤ 106), k (0 ≤ k ≤ n).
Output
For each case, output the case number and the desired value. Since the result can be very large, you have to print the result modulo 1000003.
Sample Input
3
4 2
5 0
6 4
Sample Output
Case 1: 6
Case 2: 1
Case 3: 15
两种方法可求解,不过感觉大致上是差不多的。。。
题意:数学组合问题改编成费马小定理—>逆元。。。组合 C(n,m) = n! / (m! * (n - m)! )
逆元:由费马小定理a ^ (p-1) = 1 (%p),两边同时除去a——a ^ (p-2) = a^-1 (%p),得a的逆元a^-1 = a ^ (p-2)。
题解:当n 不大于 1e6 时可以考虑打表,先把每个数的介乘打表,再把每个数的逆元打表,然后就出来答案了
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define M 1000003#define LL long longLL pre[M], pows[M];void init()//将每个数的介乘打表 { pre[0] = 1; for(int i=1; i<M; i++) { pre[i] = pre[i-1] * i % M; }} LL quickpow(LL n, LL m, LL k)//用快速幂求逆元 { LL res = 1; while(m) { if(m & 1) { res = res * n % k; } m >>= 1; n = n * n % k; } return res;}void init2()//将每个数的介乘的逆元打表 { pows[0] = 1; pows[1] = 1; for(LL i=2; i<M; i++) { pows[i] = quickpow(pre[i], M-2, M);//传入数据是每个数的介乘 }}int main(){ int t; LL ans, n, m, a, b, c; scanf("%d", &t); init(); init2(); for(int ca=1; ca<=t; ca++) { scanf("%lld%lld", &n, &m); a = pre[n]; b = pows[m]; c = pows[n-m]; ans = (a * c % M) * b % M; printf("Case %d: %lld\n", ca, ans); } return 0;}
lucas定理求解。。。。。lucas大模板题
根据百度可知:C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p链接在此
然后就可以开始我们构造函数之路了
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define LL long long#define M 1000003LL fac[M];void fact()//构造阶乘{ fac[0] = 1; for(int i=1; i<M; i++) { fac[i] = fac[i-1] * i % M; }}LL quickpow(LL n, LL m, LL k)//快速幂{ LL res = 1; while(m) { if(m & 1) { res = res * n % k; } m >>= 1; n = n * n % k; } return res;}LL comb(LL n, LL m, LL k)//这个是组合函数{ LL ans = 1; ans = fac[n] * quickpow(fac[m]*fac[n-m]%k, k-2, k) % k; return ans;}LL lucas(LL n, LL m, LL k)//这个是lucas{ LL ans = 1; if(m > n) return 0;//这个应是显然咯 while(n && m && ans) { ans = ans * comb(n%k, m%k, k); n /= k; m /= k; } /* return comb(n%k, m%k, k) * lucas(n/k, m/k, k);递归方法 */ return ans;}int main(){ int t; LL n, m; fact(); scanf("%d", &t); for(int ca=1; ca<=t; ca++) { scanf("%lld%lld", &n, &m); printf("Case %d: %lld\n", ca, lucas(n, m, M)); } return 0;}
- Lightoj 1067(逆元)
- 【LightOJ】1067 - Combinations(Lucas & 逆元)
- 【Lightoj 1067】+ 逆元 + 预处理
- LightOJ - 1067 Combinations(快速幂+逆元)
- lightoj 1067 - Combinations (组合数、乘法逆元)
- Lightoj 1067【逆元模板(求C(N,M))】
- lightoj 1102 - Problem Makes Problem(组合数+逆元)
- LightOJ-1102-组合数学,逆元
- LightOJ - 1067 数论<100000左右的组合数取模求法《逆元》>
- lightoj 1102 - Problem Makes Problem (组合+逆元)
- Lightoj 1067
- Lightoj 题目1067 Combinations(lucas)
- LightOJ 1067 - Combinations (Lucas定理)
- Light OJ 1067 Combinations(逆元)
- LightOJ 1067 组合数求模
- lightOJ 1067 - Combinations
- LightOj 1067(Lucas)
- lightoj 1067 - Combinations
- 转载:做技术真的没前途前途吗?
- 网上知识点汇总一
- EventBus使用详解(二)——EventBus使用进阶
- HDU 1848 Fibonacci again and again
- CKEditor使用配置
- Lightoj 1067(逆元)
- [lintcode 14] First Position of Target
- android handler机制的原理
- php 数据类型转换 实例
- iOS--- 不一样的NSLog打印
- 7月份实习总结
- [Linux]环境配置之jdk的安装
- linux学习第六篇:安装Percona Server-Mysql
- tap,touch,touchstart事件与click事件的区别