题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5446

题目大意:求C(n, m) % M, 其中M为不同素数的乘积,即M=p1*p2*...*pk, 1≤k≤10。1≤m≤n≤10^18。

分析: 如果M是素数,则可以直接用lucas定理来做,但是M不是素数,而是素数的连乘积。令C(n, m)为 X ,则可以利用lucas定理分别计算出 X%p1,X%p2, ... , X % pk的值,然后用中国剩余定理来组合得到所求结果。

比较坑的地方是,中间结果会超long long 范围,要用类似于快速幂的方法来模拟。

参考代码:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <string.h>
  4. using namespace std;
  5. long long a[];
  6. long long Mod;
  7. long long c[];
  8. long long w[];
  9. long long Egcd(long long a,long long b,long long &x,long long &y){
  10. long long d;
  11. if(b==){
  12. x=;y=;
  13. return a;
  14. }
  15. d=Egcd(b,a%b,y,x);
  16. y-=a/b*x;
  17. return d;
  18. }
  19. long long cal(long long a, long long b, long long mod) {//模拟a*b%mod
  20. long long ret = ;
  21. while(b) {
  22. if(b & ) ret = (ret + a) % mod;
  23. a = (a + a) % mod;
  24. b >>= ;
  25. }
  26. return ret;
  27. }
  28.  
  29. long long c_r(int len){//中国剩余定理
  30. int i;
  31. long long d,x,y,n,m,ret;
  32. ret=;
  33. n=;
  34. for(i=;i<len;i++)
  35. n*=c[i];
  36. for(i=;i<len;i++){
  37. m=n/c[i];
  38. d=Egcd(m,c[i],y,x);
  39. y=(c[i]+y%c[i])%c[i];
  40. if( i&) y -= c[i];
  41. //if(y>c[i]-y) y=y-c[i];
  42. ret=(ret+cal(y*m, w[i], n))%n;
  43. }
  44. return (n+ret%n)%n;
  45. }
  46.  
  47. void init(){
  48. int i;
  49. memset(a, , sizeof(a));
  50. a[]=;
  51. for(i=;i<Mod;i++)
  52. a[i]=a[i-]*i%Mod;
  53. }
  54.  
  55. long long gcd(long long a,long long b){
  56. if(b==) return a;
  57. return gcd(b,a%b);
  58. }
  59.  
  60. long long choose(long long n,long long m){
  61. if(m>n)return ;
  62. else if(n==m) return ;
  63. long long nn=a[n],mm=a[m]*a[n-m]%Mod;
  64. long long d=gcd(nn,mm);
  65. nn/=d;
  66. mm/=d;
  67. long long x,y;
  68. Egcd(mm,Mod,x,y);
  69. x=(x+Mod)%Mod;
  70. return (x*nn)%Mod;
  71. }
  72.  
  73. long long work(long long n,long long m){//lucas
  74. long long ret=;
  75. while(n&&m){
  76. ret*=choose(n%Mod,m%Mod);
  77. ret%=Mod;
  78. n/=Mod,m/=Mod;
  79. }
  80. return ret;
  81. }
  82.  
  83. int main(){
  84. int T;
  85. long long n,m;
  86. int k;
  87. scanf("%d",&T);
  88. while(T--){
  89. cin >> n >> m >> k;
  90. if(m > n-m) m = n-m;
  91. for(int i=;i<k;i++){
  92. cin >> c[i];
  93. Mod=c[i];
  94. init();
  95. w[i]=work(n,m);
  96. }
  97. cout << c_r(k) << endl;
  98. }
  99. }

HDU 5446 Unknown Treasure(lucas + 中国剩余定理 + 模拟乘法)的更多相关文章

  1. HDU 5446 Unknown Treasure Lucas+中国剩余定理+按位乘

    HDU 5446 Unknown Treasure 题意:求C(n, m) %(p[1] * p[2] ··· p[k])     0< n,m < 1018 思路:这题基本上算是模版题了 ...

  2. HDU 5446 Unknown Treasure Lucas+中国剩余定理

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5446 Unknown Treasure 问题描述 On the way to the next se ...

  3. hdu 5446 Unknown Treasure lucas和CRT

    Unknown Treasure Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...

  4. hdu 5446 Unknown Treasure Lucas定理+中国剩余定理

    Unknown Treasure Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  5. Hdu 5446 Unknown Treasure (2015 ACM/ICPC Asia Regional Changchun Online Lucas定理 + 中国剩余定理)

    题目链接: Hdu 5446 Unknown Treasure 题目描述: 就是有n个苹果,要选出来m个,问有多少种选法?还有k个素数,p1,p2,p3,...pk,结果对lcm(p1,p2,p3.. ...

  6. ACM学习历程—HDU 5446 Unknown Treasure(数论)(2015长春网赛1010题)

    Problem Description On the way to the next secret treasure hiding place, the mathematician discovere ...

  7. hdu 5446 Unknown Treasure 中国剩余定理+lucas

    题目链接 求C(n, m)%p的值, n, m<=1e18, p = p1*p2*...pk. pi是质数. 先求出C(n, m)%pi的值, 然后这就是一个同余的式子. 用中国剩余定理求解. ...

  8. HDU 5446 Unknown Treasure(Lucas定理+CRT)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5446 [题目大意] 给出一个合数M的每一个质因子,同时给出n,m,求C(n,m)%M. [题解] ...

  9. HDU 5446——Unknown Treasure——————【CRT+lucas+exgcd+快速乘+递推求逆元】

    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 o ...

随机推荐

  1. 搭建第一个netty程序

    来自action In netty 自己修改一点点 主要依赖 <dependencies> <dependency> <groupId>io.netty</g ...

  2. 【IOS打包】ARCHIVE FAILED:Command CodeSign failed with a nonzero exit code

    [问题] [解决办法] 用xcode打开项目 command + k 重启电脑 参照:xcode打包报错command codesign failed with a nonzero exit code ...

  3. 前端必须掌握的 docker 技能(3)

    概述 作为一个前端,我觉得必须要学会使用 docker 干下面几件事: 部署前端应用 部署 nginx 给部署的 nginx 加上 https 使用 docker compose 进行部署 给 ngi ...

  4. web搜索功能测试

    功能方面: 是否能按指定条件查到正确.完整的结果,具体表现: 1.1录入条件为可查到结果的正常关键字.词.语句,检索到的内容.链接正确性: 1.2录入条件为不可查到结果的关键字.词.语句: 1.3录入 ...

  5. 用apicloud+vue的VueLazyload实现缓存图片懒加载

    <script src="../../script/vue-lazyload.js"></script><img v-lazy="remot ...

  6. python使用相对路径创建文件夹

    两个py文件,一个是al文件夹下的test1.py,一个是和al文件夹同层的test2.py test1.py代码如下: import os def test(): path = './source_ ...

  7. 一文学会Go - 2 数据结构与算法实践篇

    练习:使用go语言实现冒泡排序和归并排序 冒泡排序是所有排序算法中最简单的,练习时先实现它: func bubbleSort(array []int) { n := len(array) ; j &l ...

  8. 4.站点克隆wget----隐写术图片----backbox linux

    站点克隆wget sudo bash cd Desktop/Cloned wget -h clear wget -mk https://help.ubuntu.com/ 隐写术图片 想想朋友圈的图片 ...

  9. python pandas 自动生成批量测试数据插入数据库 mysql

    1.python连接数据库游标 # coding:utf-8 from sqlalchemy import create_engine class connet_databases: def __in ...

  10. MySQL的count(*)性能怎么样?

    对于count(主键id)来说,innodb引擎会遍历整张表,把每一行的id值都取出来,返回给server层,server层判断id值不为空,就按行累加 对于count(1)来说,innodb引擎遍历 ...