HDU 5446 Unknown Treasure(Lucas定理+中国剩余定理)
2015-09-13 16:44
204 查看
题意:给一个组合数C(n, m) (n, m<1e18)和 mod(mod<1e18),求这个组合数模除mod的值。
思路:先用lucas定理求出组合数模除每个质因子的解,然后用中国剩余定理来进行求解,要注意两个long long类型相乘可能会爆,要把乘法改成加法的形式。
思路:先用lucas定理求出组合数模除每个质因子的解,然后用中国剩余定理来进行求解,要注意两个long long类型相乘可能会爆,要把乘法改成加法的形式。
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; typedef long long LL; typedef long long lint; lint p[12] ; lint num[12] ; LL multi_mod(LL a, LL b, LL c) { a %= c; b %= c; LL ret = 0; while(b) { if(b&1) { ret += a; if(ret >= c) ret -= c; } a <<= 1; if(a>=c) a-=c; b >>= 1; } return ret; } LL quick_mod(LL a, LL p, LL n) { if(p == 0) return 1; LL ans = quick_mod(a, p/2, n); ans = multi_mod(ans, ans, n); if(p%2 == 1) ans = multi_mod(ans, a, n); return ans; } LL pow_mod(LL a, LL p, LL n) { if(p == 0) return 1; LL ans = pow_mod(a, p/2, n); ans = ans * ans % n; if(p%2 == 1) ans = ans * a % n; return ans; } LL C(LL n, LL m , lint p) { if(m > n) return 0; LL ans = 1; for(int i=1; i<=m; i++) { LL a = (n + i - m) % p; LL b = i % p; ans =ans* (a*pow_mod(b, p-2 , p) %p) %p ; } return ans; } LL Lucas(LL n, LL m , lint p ) { if(m == 0) return 1; //cout << "gan" << endl; return C(n % p, m % p , p) * Lucas(n / p, m / p , p) % p; } lint CRT( lint a[] , lint m[] , int n ){ if(n==1) return num[0]; lint M = 1 ; for( int i = 0 ; i < n ; i++ ) M = M * m[i] ; //cout << M << endl ; lint ret = 0 ; for( int i = 0 ; i < n ; i++ ){ lint x ; lint tmp = M / m[i] ; //cout << m[i] << tmp-2 << tmp << endl ; x = quick_mod( tmp , m[i]-2, m[i] ) ; //cout << x << ' ' << tmp << ' ' << M << endl ; lint y = multi_mod( tmp , x , M ) ; //cout << x * tmp % M << endl; y = multi_mod( tmp*x % M, num[i] , M ) ; ret = ( ret + y ) % M ; //cout << ret << endl ; //cout << ret <<endl; } return ( ret + M ) % M ; } int main() { //freopen( "input.txt" , "r" , stdin ) ; int T; scanf("%d", &T); while(T--) { lint n , m ; int t ; scanf("%I64d%I64d%d", &n, &m, &t); //cout << quick_mod( 2 , 5 , 7 ) ; for( int i = 0 ; i < t ; i++ ){ cin >> p[i] ; num[i] = Lucas( n , m , p[i] ) ; //cout << num[i] << endl ; } lint ans = CRT( num , p , t ) ; printf("%I64d\n", ans ); } return 0; }
相关文章推荐
- [解决]dyld: Library not loaded: @rpath/libswiftCore.dylib / Image not found
- Monit 简单实践
- Sort Colors
- HDU 5441 Travel
- AD帐号批量导入导出
- 为大二软件工程专业大学生解答的几个问题
- Introducing Visual Studio’s Emulator for Android
- 二叉搜索树
- Swap Nodes in Pairs
- HDU 5438.Ponds【2015 ACM/ICPC Asia Regional Changchun Online】【DFS】9月13
- SPSS实例(共四十篇)
- 文本编辑三剑客之awk
- IOS UI学习 UITableView Demo 实现类似QQ联系人收起和展开效果
- UIScreen 类
- 经典的冒泡排序
- 在android下获取有线和无线IP地址的方法,经测试可用
- USB设备信息各数据结构的组织关系
- 数据结构—Java语言判断单链表是否有环与寻找结环节点
- Hacker之路技能树(2)
- Hibernate 动态表名映射(数据库分表) NamingStrategy