组合数取模
来源:互联网 发布:java与xml 第3版 pdf 编辑:程序博客网 时间:2024/06/04 01:33
[组合数取模](com.cpp/in/out 1s 128M)
题目描述
给出N,M,P,求C(N,M) Mod P
1<=M<=N<=10^6,1<=P<=10^5,P可能为合数
输入格式:一行给出N,M,P
输出格式:一行,输出最终结果
样例输入
5 2 3
样例输出
分析:此题m与n很大,如果求暴力分分钟wa,P可能为合数,用欧拉定理求逆元似乎是可行的,未写代码证明。但是我们可以通过唯一分解定理将n!/(m!*(n-m)!)其分解成一个个质因数的指数次方,然后用这些质因子的指数次方MOD P。这个指数这样求得:
设N!里含有的质因子ai,它在N!里有x个质因子ai;
M!里含有的质因子ai,它在M!里有y个质因子ai;
(N-M)!里含有的质因子ai,它在(N-M)!里有z个质因子ai;
那么就可以由 ai ^ (x-(y+z)) % P;
将所有的这样的质因子都一一的枚举出来,如上面的方法计算其指数,逐个MOD P,就可以比较好的计算出这道题。
具体程序代码为:
#include<iostream>#include<cmath>using namespace std;typedef long long LL;int n,m,P;int p[1000006],tot;bool isPrime[1000006];void aishi() //埃式筛质数 { memset(isPrime,true,sizeof(isPrime)); int t = sqrt(n); for(int i= 2; i<= t; i++){ if(isPrime[i]){ for(int j = i*i; j<= n; j+=i){ isPrime[j] = false; } } } for(int i = 2; i<= n; i++){ if(isPrime[i]) p[++tot] = i; }}LL quickMod(LL a,LL b){ //快速幂 LL ans = 1; a = a % P; while(b){ if(b%2 == 1) ans = ans * a % P; b = b/2; a = a * a % P; } return ans;}int num(int x,int k) //计算1~x之间的数中约数k的个数 { int ans = 0; while(x){ ans += (x/k); x = x/k; } return ans;}LL solve(){ LL ans = 1; for(int i = 1;i<= tot&& p[i] <= n; i++) { int x = num(n,p[i]); int y = num(m,p[i]); int z = num(n-m,p[i]); ans = (ans * quickMod(p[i],x-(y+z))) % P; } return ans;}int main(){ cin >> n >> m >> P; aishi(); LL ans = solve(); cout << ans << endl; return 0;}
阅读全文
0 0
- 组合数取模
- 【组合数取模】
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 组合数取模
- 第10章 异常处理
- 去掉DevExpress试用版提示框的解决办法
- 基于Skip-Thought的Sentence2Vec神经网络实现
- Http请求中的Context-Type及其SpringMVC中的使用
- zookeeper的日志文件和快照的可视化
- 组合数取模
- 第四周项目3
- 集成学习之Adaboost算法原理小结
- Scrapy爬虫笔记
- 2017 icpc 南宁赛区 F.Overlapping Rectangles(重叠矩形的最大面积+线段树模板)
- java 技术资料,jar包下载,工具下载等资源网站
- HDOJ2009(预处理)
- css background-image 自适应宽高
- Hive基础(3):表分类、视图、数据加载方式、数据的导出、本地模式