hdoj-5446-Unknown Treasure
来源:互联网 发布:手机拍电影特效软件 编辑:程序博客网 时间:2024/05/19 15:19
Problem Description
On the way to the next secret treasure hiding place, the mathematician discovered a cave unknown to the map. The mathematician entered the cave because it is there. Somewhere deep in the cave, she found a treasure chest with a combination lock and some numbers on it. After quite a research, the mathematician found out that the correct combination to the lock would be obtained by calculating how many ways are there to pick m different apples among n of them and modulo it with M. M is the product of several different primes.
Input
On the first line there is an integer T(T≤20) representing the number of test cases.
Each test case starts with three integers n,m,k(1≤m≤n≤1018,1≤k≤10) on a line where k is the number of primes. Following on the next line are k different primes p1,…,pk. It is guaranteed that M=p1⋅p2⋅⋅⋅pk≤1018 and pi≤105 for every i∈{1,…,k}.
Output
For each test case output the correct combination on a line.
Sample Input
1
9 5 2
3 5
Sample Output
6
题意:给你n,m,num,然后给你num个数,k1,k2….,knum,然后让你求C(n,m)%(k1*k2*….*knum)
题解:lucas+中国剩余定理裸题,注意在中国剩余定理里面,有可能两数相乘爆long long,要用按位乘的方式,但是这样的话exgcd返回值如果是负数就会出错,所以乘之前要取模成正的。
首先,C(n,m)%k我们是会求的,大概这部分子问题是一个很经典的题目。
假设你会求了,那么我们就可以由此得到num个答案,是%k1,k2,k3….knum后得到的值
然后我们就可以看出就是类似韩信点兵一样的题,三个人一组剩了2个,五个人一组剩了2个这种……
这时候,就用中国剩余定理处理处理就好了
注意ll*ll会爆,所以得手写个快速乘法
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 1e5 + 5;ll fac[maxn], inv[maxn];ll pow_mod(ll a, int n, int mod){ ll ret = 1; while (n) { if (n&1) ret = ret * a % mod; a = a * a % mod; n >>= 1; } return ret;}void init(int n){ fac[0] = 1; for (int i = 1; i < n; i++) fac[i] = fac[i-1] * i % n; inv[n-1] = pow_mod(fac[n-1], n-2, n); for (int i = n - 2; i >= 0; i--) inv[i] = inv[i+1] * (i+1) % n;}ll C (int n, int m, int mod) { if (m > n || m < 0 || n < 0) return 0; return fac[n] * inv[m] % mod * inv[n-m] % mod;}ll lucas(ll n, ll m, int mod){ if (m == 0) return 1; return lucas(n / mod, m / mod, mod) * C(n % mod, m % mod, mod) % mod;}ll exgcd(ll a, ll b, ll& x, ll& y){ if (b == 0) { x = 1; y = 0; return a; } ll d = exgcd(b, a % b, y, x); y -= x * (a / b); return d;}ll mul(ll a, ll b, ll mod){ a = (a % mod + mod) % mod; b = (b % mod + mod) % mod; ll ret = 0; while(b){ if(b&1){ ret += a; if(ret >= mod) ret -= mod; } b >>= 1; a <<= 1; if(a >= mod) a -= mod; } return ret;}ll china(int n, ll* a, ll* m){ ll M = 1, d, y, x = 0; for (int i = 0; i < n; i++) M *= m[i]; for (int i = 0; i < n; i++) { ll w = M / m[i]; exgcd(m[i], w, d, y); x = (x + mul(mul(y, w, M), a[i], M)); } return (x + M) % M;}int main (){ int cas, k; ll n, m, a[15], p[15]; scanf("%d", &cas); while (cas--) { scanf("%lld%lld%d", &n, &m, &k); for (int i = 0; i < k; i++) { scanf("%lld", &p[i]); init(p[i]); a[i] = lucas(n, m, p[i]); } printf("%lld\n", china(k, a, p)); } return 0;}
- hdoj-5446-Unknown Treasure
- hdoj 5446 Unknown Treasure 【lucas + CRT】
- HDOJ 题目5446 Unknown Treasure(Lucas+费马小定理+CRT)
- HDU 5446 Unknown Treasure
- HDU 5446 Unknown Treasure
- HDU 5446 Unknown Treasure
- HDU 5446 Unknown Treasure
- HDU 5446 Unknown Treasure
- HDU 5446 Unknown Treasure
- HDU 5446 Unknown Treasure
- HDU 5446 Unknown Treasure(Lucas定理+CRT)
- HDU 5446 Unknown Treasure Lucas+CRT
- HDU 5446 Unknown Treasure [lucas+CRT]【数论】
- HDU5446 Unknown Treasure
- Unknown Treasure HDU
- HDU 5446 Unknown Treasure(Lucas定理+中国剩余定理)
- hdu 5446 Unknown Treasure(lucas+中国剩余定理)
- hdu 5446 Unknown Treasure (Lucas定理+CRT+快速乘)
- 开发常用单词
- 创建新项目的目录(MVP)
- html布局中form表单的简单用法和常用属性设置
- AIDL
- MyBatis Excutor 拦截器的巧妙用法
- hdoj-5446-Unknown Treasure
- Kafka 单机安装、测试和监控
- 机器学习(Machine Learning)&深度学习(Deep Learning)资料汇总
- 数据结构实验之栈四:括号匹配
- Binder机制
- Spring的体系结构
- 数据结构实验之栈二:一般算术表达式转换成后缀式
- Java:常用集合类(List、Map、Set、Queue、Stack)
- 10.5号新生练习赛题解