2017-07-25 51nod 1119 组合数取模 某数关于质数的逆元
来源:互联网 发布:公路基础数据库系统 编辑:程序博客网 时间:2024/06/07 12:05
机器人走方格(是方格啊方格啊不是格点啊)
题目描述:
M * N的方格,一个机器人从左上走到右下,只能向右或向下走。有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果。INPUT:
1行2个数M,N,中间用空格隔开.(2 <= m,n <= 1000000)
OUTPUT:
输出走法的数量 Mod 10^9 + 7
样例输入:
2 3
样例输出:
3
组合数取模,底数的规模达到了十的六次方 再乘二.
如果用最开始的寻找公约数然后约分再取模会发现只支持到十的五次方而且还会冒(哈哈哈哈哈哈嗝)
所以用最原始的公式即(n!)/{m!*(n-m)!} (这道题里面,n=(M-1)+(N-1),m=N-1或者m=M-1)(为什么都减了一个1,这个需要你好好读题)
首先打表数组data,data[k]即为k!对题目要求的MOD取模后的结果(用递归的方式实现)
然后这里有一个(并不)有趣的结论就是b关于某个质数x的逆元和(b mod x)关于质数x的逆元是一样的
上面这个结论也许可以扩展,时间有限就没有继续深究下去
所以打表data里面的数据可以直接拿来用(打表的时候已经对MOD取过模了)
然后题目中的MOD是一个质数,根据费马小定理可知某个数a关于质数的某个逆元为a^(p-2)(表达并不准确)
这个a^(p-2)可以用快速幂来解决,函数中的取模即为题目中的MOD
所以分子上的除法计算就会变成与一个逆元data[N-1]^(MOD-2)和另一个逆元data[M-1]^(MOD-2)相乘
最后答案就变成 data[M+N-2] * data[N-1]^(MOD-2) * data[M-1]^(MOD-2)
然后上面三个因式(1)(2)(3) ,(2)(3)用之前先取个模
然后(1)乘以(2)先取个模,然后乘以(3)再取个模
然后就是res
代码如下
#include <stdio.h>#include <stdlib.h>#define MOD 1000000007long long int data[2000010];//不是1000010,因为M+N<=2000000,底数的规模是看M+Nlong long int quick_mod(long long int a,long long int p,long long int mod)//计算(a^p)%mod即快速幂 用于计算指数p特别大的情况{//计算(a^p)%mod long long int res=1; while(p) { if(p&1) res=res*a%mod;//int有可能会冒,视情况换成long long(这里换了) p>>=1;//就是 p=p/2 a=(a*a)%mod; } return res;}long long int cn(int n,int k){//cn,组合数英文combinatorial number的缩写 long long int res; res=data[n]; res=(res*quick_mod(data[k],MOD-2,MOD))%MOD;//利用费马小定理取巧求逆元 (b*b^(p-2))mod p=1,因为质数p的欧拉函数值就是p-1 res=(res*quick_mod(data[n-k],MOD-2,MOD))%MOD;//啊对这两行代码是抄的,因为原来的长达五六行的自己写的啰嗦版本找不到了,又一次证明我的代码相当冗余 return res;}int main(){ int a,b,minn,i; long long int res; data[0]=1; for(i=1;i<2000010;i++) { data[i]=data[i-1]*i; data[i]=data[i]%MOD;//打表,边打表边取模 //printf("%lld\n",data[i]); } while(scanf("%d%d",&a,&b)!=EOF) { if(a<b) minn=a; else minn=b; res=cn(a+b-2,minn-1);//为什么这里要减二——认真读题,机器人走的是格子不是格点 printf("%lld\n",res); } return 0;}
然后就是res
- 2017-07-25 51nod 1119 组合数取模 某数关于质数的逆元
- 51nod oj 1256 1119 1013 1083 1014 1081<组合数+逆元+快速幂,DP,枚举,树状数组>
- 51nod 1119 机器人走方格V2(求组合数,费马小定理+快速幂/逆元+gcd)
- 关于数论中的互质数的最大不能组合数
- 51nod 1118 机器人走方格(组合数【逆元】,dp)
- Codeforces785D (组合数的逆元)
- 51 NOD 1119 机器人走方格 V2(组合数学 + 逆元)
- 51nod 1119 机器人走方格 V2【组合数学+逆元】
- 乘法逆元(对于质数模数的乘法逆元)
- 组合数、逆元,数学
- FZU2282-组合数-逆元
- 51 nod 质数中的质数
- 关于逆元的概念、用途和可行性的思考(附51nod 1013 和 51nod 1256)
- 2017-10-22 51nod 1120 卢卡斯定理 Lucas 组合数取模 卡特兰数
- 51nod 1677 treecnt【树,组合数】
- 51nod 1677 treecnt 组合数
- 51nod 1453 抽彩球(组合数)
- 【组合数】51Nod 1627 瞬间移动
- 关于NoSQL与SQL的区别
- Android--方法和封装类记录
- IPMIversion2.0学习笔记1
- ios-屏幕适配
- NAT模式静态指定虚拟机的ip地址方法
- 2017-07-25 51nod 1119 组合数取模 某数关于质数的逆元
- nyoj283对称排序
- Loss Max-Pooling for Semantic Image Segmentation(2017cvpr)
- IPMI version 2.0 学习笔记2
- 文件操作
- HUD 6035 Colorful Tree dfs序||树形dp
- MySQL的常用函数
- 最全面的Java多线程用法解析
- unity简单封装的网络请求