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 kdifferent 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
 
Source
 

题目大意:让求C(n,m)%(∏pi) 这个式子的值。

中国剩余定理:

解题思路:首先用lucas定理将求C(a,b)%p转化成求解∏C(bi,ai),这样,我们可以得到c[i]数组。然后用中国剩余定理来求x0的值,即为答案。在求解的过程中需要用到扩展欧几里得来求解Mi的逆元,由于Mi比较大,所以在乘积的时候会爆数据范围,所以改成快速乘取模的方式代替直接乘积。

#include<bits/stdc++.h>
using namespace std;
typedef long long INT;
const int maxp=1e5+200;
INT p[15],c[15];
INT fac[maxp],inv[maxp];
INT powmod(INT a,INT n,INT mod){//快速幂取模
INT ret=1;
while(n){
if(n&1){
ret=ret*a%mod;
}
n>>=1;
a = a*a%mod;
}
return ret;
}
INT mulmod(INT a,INT b,INT mod){//快速乘取模
a = (a%mod + mod) % mod; //用扩展欧几里得求出的值可能为负值
b = (b%mod + mod) % mod; //用扩展欧几里得求出的值可能为负值
INT ret=0;
while(b){
if(b&1){
ret = (ret+a)%mod;
}
b >>= 1;
a = (a<<1) % mod;
}
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]=powmod(fac[n-1],n-2,n);
for(int i=n-2;i>=0;i--){
inv[i] = inv[i+1] * (i+1) % n;
//fac[n]*inv[fac[n]]≡1%p ==> fac[n-1]*(n*inv[fac[n]])≡1%p
}
}
INT cm(INT n,INT m,INT mod){ //用逆元求组合数取模
if(n<0||m<0||m>n){
return 0;
}
return fac[n]*inv[n-m]%mod*inv[m]%mod;
}
INT lucas(INT n,INT m,INT mod){//lucas递归求P进制时的c
if(m==0){
return 1;
}
return lucas(n/mod,m/mod,mod) * cm(n%mod,m%mod,mod) % mod;
}
INT exgcd(INT a,INT b,INT &x,INT &y){ //求b关于模a的逆元。放在y中
if(b==0) { x = 1; y = 0; return a; }
INT d = exgcd(b, a%b , y, x);
y -= x * (a / b);
return d;
}
void CRT(INT k){//中国剩余定理求解一元线性同余方程组
INT M=1,x,y;
INT ans=0;
for(int i=1;i<=k;i++){
M *= p[i];
}
for(int i=1;i<=k;i++){
INT Mi=M/p[i];
exgcd(p[i],Mi,x,y);
ans = (ans+mulmod(mulmod(y,Mi,M),c[i],M))%M ;
}
printf("%I64d\n",ans);
}
int main(){
INT n,m,k;
int t;
scanf("%d",&t);
while(t--){
scanf("%I64d%I64d%I64d",&n,&m,&k);
for(int i=1;i<=k;i++){
scanf("%I64d",&p[i]);
init(p[i]);
c[i] = lucas(n,m,p[i]);
}
CRT(k);
}
return 0;
}

  

HDU 5446——Unknown Treasure——————【CRT+lucas+exgcd+快速乘+递推求逆元】的更多相关文章

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

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

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

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

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

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

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

  5. hdu 5446 Unknown Treasure lucas和CRT

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

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

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

  7. hdu 5446 Unknown Treasure 卢卡斯+中国剩余定理

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

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

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

  9. HDU 5446 Unknown Treasure

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

随机推荐

  1. DotNet经典面试题(转载)

    .Net基础常见 什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS.CLS.CLR分别作何解释? 答: 1应用程序域可以理解为一种轻量级进程.起到安全的作用 ...

  2. 【LeetCode每天一题】Remove Duplicates from Sorted List(移除有序链表中的重复数字)

    Given a sorted linked list, delete all duplicates such that each element appear only once. Example 1 ...

  3. c语言参考书籍

    很惭愧没能把c++学的很好,毕竟离开始工作只有2年时间,对自己要求不要过高,慢慢来吧.话说知道自己的不足,以后要更加抓紧了!fighting~ 现在计划着把c语言给学习一下了,当然这次指的是深入地学习 ...

  4. nagios安装使用指南

    话不多说,下面开始,nagios具体的介绍,可以搜一下,这篇文章为作者在实际操作中整理出来,写出来的都是负责人的内容~ 环境准备 此文档共用2台服务器的配置,操作系统均为centOS6.7,安装用户都 ...

  5. DB2存储过程标准

    CREATE OR REPLACE PROCEDURE "FCT"."PROC_FCT_DSB_SERIES"(IN ACCOUNTING_DATE DATE) ...

  6. 模板 Trie树

    模板 Trie树 code: #include <iostream> #include <cstdio> using namespace std; const int wx=2 ...

  7. asp.net core 自定视图主题 实现IViewLocationExpander接口

    新建ThemeViewLocationExpander.cs 实现IViewLocationExpander接口 /// <summary> /// 自定视图主题 实现IViewLocat ...

  8. [转载]C#实现获取浏览器信息

      原文地址:C#实现获取浏览器信息作者:flywithme Request.Browser.MajorVersion.ToString();//获取客户端浏览器的(主)版本号 Request.Bro ...

  9. 利用zookeeper生成唯一id

    package com.cxy.com.cxy.curator; import java.util.concurrent.ExecutorService; import java.util.concu ...

  10. Qt 学习之路 2(13):对话框简介

    Qt 学习之路 2(13):对话框简介  豆子  2012年9月14日  Qt 学习之路 2  53条评论 对话框是 GUI 程序中不可或缺的组成部分.很多不能或者不适合放入主窗口的功能组件都必须放在 ...