n中选m个模M,M为多个素数之积 $n, m, k (1 \leq m \leq n \leq 10^{18}, 1 \leq k \leq 10)$,$M = p_1 · p_2 · · · p_k ≤ 10^{18}$,$p_i \leq 10^5$

由于n,m很大组合数自然想到lucas,但是如果直接用M会因为M太大lucas就没什么用了,所以考虑以构成M的素因子为模数分别对组合数的lucas构建k个同余方程,这样就能得到模M下组合数了。了解题目意思后就很裸了

注意每个不同模数下的逆元、阶乘的模数也不同阿...

/** @Date    : 2017-10-11 12:56:59
* @FileName: J.cpp
* @Platform: Windows
* @Author : Lweleth (SoungEarlf@gmail.com)
* @Link : https://github.com/
* @Version : $Id$
*/
#include <bits/stdc++.h>
#define LL long long
#define PII pair
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std; const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8; LL fac[N];
LL inv[N];
LL p[20];
LL r[20];
LL mod;
void init(int n, LL mod)
{
fac[0] = fac[1] = 1;
inv[0] = inv[1] = 1;
for(int i = 2; i < n; i++)
{
fac[i] = fac[i - 1] * i % mod;
inv[i] = (mod - mod / i) * inv[mod % i] % mod;
}
for(int i = 2; i < n; i++)
(inv[i] *= inv[i - 1]) %= mod;
} LL C(LL n, LL m, LL mod)
{
if(m > n)
return 0;
LL ans = 0;
ans = ((fac[n] * inv[m] % mod)* inv[n - m]) % mod;
return ans;
} LL lucas(LL n, LL m, LL mod)
{
if(m == 0)
return 1;
return C(n % mod, m % mod, mod) * lucas(n / mod, m / mod, mod) % mod;
} LL exgcd(LL a, LL b, LL &x, LL &y)
{
LL d = a;
if(b == 0)
x = 1, y = 0;
else
{
d = exgcd(b, a % b, y, x);
y -= (a / b) * x;
}
return d;
} LL mul(LL a, LL b, LL mod)
{
while(a < 0)
a += mod;
while(b < 0)
b += mod;
LL ans = 0;
while(b)
{
if(b & 1)
ans = (ans + a) % mod;
a = (a + a) % mod;
b >>= 1;
}
return ans;
} LL CRT(LL n, LL rem[], LL mod[])
{
LL M = 1, x, y;
for(int i = 0; i < n; i++)
M *= mod[i];
LL res = 0;
for(int i = 0; i < n; i++)
{
LL t = M / mod[i];
exgcd(t, mod[i], x, y);
res = (res + mul(mul(t , rem[i], M), x, M)) % M;
} return (res % M + M) % M;
} int main()
{
int T;
cin >> T;
while(T--)
{
LL n, m, k;
scanf("%lld%lld%lld", &n, &m, &k);
mod = 1LL;
for(int i = 0; i < k; i++)
{
scanf("%lld", p + i);
init(p[i], p[i]);
r[i] = lucas(n, m, p[i]);
}
LL ans = CRT(k, r, p);
printf("%lld\n", ans);
}
return 0;
}

HDU 5446 lucas CRT的更多相关文章

  1. hdu 5446 lucas+crt+按位乘

    http://acm.hdu.edu.cn/showproblem.php?pid=5446 题意:题目意思很简单,要你求C(n,m)mod p的值 p=p1*p2*...pn; 题解:对于C(n,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. 中国剩余定理&Lucas定理&按位与——hdu 5446

    链接: hdu 5446 http://acm.hdu.edu.cn/showproblem.php?pid=5446 题意: 给你三个数$n, m, k$ 第二行是$k$个数,$p_1,p_2,p_ ...

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

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

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

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

  6. hdu 5446 Unknown Treasure lucas和CRT

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

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

  8. HDU 5446 CRT+Lucas+快速乘

    Unknown Treasure Problem Description On the way to the next secret treasure hiding place, the mathem ...

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

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

随机推荐

  1. 【Python】LeetCode-155

    一.题目 Design a stack that supports push, pop, top, and retrieving the minimum element in constant tim ...

  2. PHP 中各种命名规则的总结

    一般约定而言 类.函数和变量的名字应该是能够让代码阅读者能够容易地知道这些代码的作用,应该避免使用凌磨两可的命名. 以下是在开发过程中常见的命名规则总结 1.类的命名 使用大写字母作为词的分割,其余的 ...

  3. behavior

    http://www.css88.com/book/css/properties/only-ie/behavior.htm 语法: behavior:<url> | url(#objID) ...

  4. springmvc+mybatis 根据数据的id删除数据

    1. 数据库表 2. notices.jsp <form action="#" method="post"> <fieldset> &l ...

  5. BZOJ5305 HAOI2018苹果树(概率期望+动态规划)

    每种父亲编号小于儿子编号的有标号二叉树的出现概率是相同的,问题相当于求所有n个点的此种树的所有结点两两距离之和. 设f[n]为答案,g[n]为所有此种树所有结点的深度之和,h[n]为此种树的个数. 枚 ...

  6. 【刷题】BZOJ 3551 [ONTAK2010]Peaks加强版

    Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...

  7. 【BZOJ1052】覆盖问题(贪心)

    [BZOJ1052]覆盖问题(贪心) 题面 BZOJ 洛谷 题解 这题好神仙啊. 很明显可以看出来要二分一个边长. 那么如何\(check\)呢? 我们把所有点用一个最小矩形覆盖, 那么必定每个边界上 ...

  8. 洛谷 P2389 电脑班的裁员 解题报告

    题意: 给定一段长为N的序列,选取其中的至多M段使这些子段和最大. 当N=1000时,我们可以采用动态规划解法 令\(dp[i][j][k]\)代表当前选至位置\(i\)处于第\(j\)段当前是否选取 ...

  9. 【uoj129】 NOI2015—寿司晚宴

    http://uoj.ac/problem/129 (题目链接) 题意 给出2~n这n-1个数,求选2个集合,使得从两集合中任意各选取1个数出来它们都互质.求方案数. Solution PoPoQQQ ...

  10. 滴滴打车CTO张博:生死战役,技术和时间赛跑

    三款产品背后的架构变迁 滴滴打车成立初衷是为了解决司机与乘客之间的信息不对称的问题,通过移动互联网和智能手机来打破信息的壁垒.从打车到专车再到顺风车,滴滴打车三款产品的背后是架构的挑战和系统的变迁. ...