链接:

hdu 5446

http://acm.hdu.edu.cn/showproblem.php?pid=5446

题意:

给你三个数$n, m, k$

第二行是$k$个数,$p_1,p_2,p_3 \cdots p_k$

所有$p$的值不相同且p都是质数

求$C(n, m) \ \%\  (p_1*p_2*p_3* \cdots *p_k)$的值

范围:$1\leq m\leq n\leq 1e18,\ 1\leq k\leq 10,p_i\leq 1e5$,保证$p_1*p_2*p_3* \cdots *p_k \leq 1e18$

分析:

我们知道题目要求$C(n, m) \ \% \ (p_1*p_2*p_3* \cdots *p_k)$的值

其实这个就是中国剩余定理最后算出结果后的最后一步求余

那$C(n, m)$相当于以前我们需要用中国剩余定理求的值

然而$C(n, m)$太大,我们只好先算出$C(n,m) \ \% \ p_1 = r_1 \\ C(n,m) \ \% \ p_2 = r_2 \\ C(n,m) \ \% \ ; p_3 = r_3 \\ \vdots \\ C(n,m) \ \% \ p_k = r_k \\$

用$Lucas$,这些$r_1,r_2,r_3 \cdots r_k$可以算出来,然后又是用中国剩余定理求答案。

注意,有些地方直接乘会爆long long,按位乘可避免。

AC代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;; typedef long long LL; void gcd(LL a, LL b, LL &d, LL &x, LL &y)
{
if (!b) { d = a; x = ; y = ; }
else { gcd(b, a % b, d, y, x); y -= x * (a / b); }
} LL quickmul(LL m, LL n, LL k)
{
m = (m % k + k) % k; n = (n % k + k) % k; //变成较小的正数
LL res = ;
while (n > )
{
if (n & )
res = (res + m) % k;
m = (m + m) % k;
n = n >> ;
}
return res;
} //计算模n下a的逆。如果不存在逆,返回-1
//ax=1(mod n)
LL inv(LL a, LL n)
{
LL d, x, y;
gcd(a, n, d, x, y);
return d == ? (x + n) % n : -;
} //n! % p
LL fact(LL n, LL p)
{
LL ret = ;
for (int i = ; i <= n; i++) ret = ret * i % p;
return ret;
} LL comp(LL n, LL m, LL p)
{
if (n < || m > n) return ;
return fact(n, p) * inv(fact(m, p), p) % p * inv(fact(n - m, p), p) % p;
} LL lucas(LL a, LL b, LL m)
{
LL ans = ;
while (a && b)
{
ans = quickmul(ans, comp(a % m, b % m, m), m) % m;
a /= m; b /= m;
}
return ans;
} //n个方程:x=a[i](mod m[i])
LL china(int n, LL* a, LL* m)
{
LL M = , d, y, x = ;
for (int i = ; i < n; i++) M *= m[i];
for (int i = ; i < n; i++)
{
LL w = M / m[i];
gcd(m[i], w, d, d, y);
x = (x + quickmul(quickmul(w,y, M),a[i],M)) % M; //直接乘会爆long long,要用按位乘
}
return (x + M) % M;
} int k;
LL n, m;
LL p[ + ],r[ + ]; int main()
{
int T;
scanf("%d", &T);
while (T--)
{
cin >> n >> m >> k;
for (int i = ; i < k; i++)
cin >> p[i];
for (int i = ; i < k; i++)
r[i] = lucas(n, m, p[i]);
LL ans = china(k, r, p);
cout << ans << endl;
} return ;
}

参考链接:https://www.cnblogs.com/linyujun/p/5199684.html

最新文章

  1. 一个flex buider 3 在eclipse下不能编译的问题解决
  2. Android--数据解析
  3. linux开机自动连接无线网络
  4. extjs form.load()加载服务端数据
  5. JSON对象的stringify()和parse()方法
  6. 卸载RedHat7自带的yum,安装并使用网易163源
  7. 【Coursera - machine learning】 Linear regression with one variable-quiz
  8. github+hexo搭建自己的博客网站(六)进阶配置(搜索引擎收录,优化你的url)
  9. 安卓开发-intent在Activity之间数据传递
  10. 编译内核时出现drivers/mfd/mxc-hdmi-core.c:36:24: fatal error: mach/clock.h: No such file or directory
  11. vue搭建
  12. eclipse 迁移项目 乱码
  13. 自己动手实现爬虫scrapy框架思路汇总
  14. Git合并一次commit到指定分支
  15. .30-浅析webpack源码之doResolve事件流(2)
  16. LeetCode 23 Merge k Sorted Lists(合并k个有序链表)
  17. linux开发模式
  18. (转)教你手工mysql拆库
  19. bzoj 1798 线段树
  20. 【JavaScript】checkBox的多选行&lt;tr&gt;信息获取

热门文章

  1. springboot+mongodb报错Caused by: java.net.ConnectException: Connection refused (Connection refused)
  2. 如何将基于对话框的MFC工程改成基于BCG的
  3. HDU1080 【LCS变形】
  4. Oculus Rift, HTC Vive, SONY PSVR的全面对比
  5. 骨骼蒙皮动画(SkinnedMesh Animation)的实现
  6. [Xcode 实际操作]七、文件与数据-(24)真机使用无线网络调试应用程序
  7. IT兄弟连 JavaWeb教程 EL表达式获取对象的属性以及数组的元素
  8. 返回零长度的数组或集合,而不是null
  9. Promise对象深入理解
  10. 01 | Jewels and Stones