51nod1119 机器人走方格 v2 费马小定理求逆元

来源:互联网 发布:java web开发进阶 编辑:程序博客网 时间:2024/05/18 02:01

组合数学
组合数
修改 隐藏话题
1119 机器人走方格 V2
基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题
 收藏
 关注
M * N的方格,一个机器人从左上走到右下,只能向右或向下走。有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果。
Input
第1行,2个数M,N,中间用空格隔开。(2 <= m,n <= 1000000)
Output
输出走法的数量 Mod 10^9 + 7。
Input示例
2 3
Output示例
3

题解:向右总共走n-1,向左总共走m-1,总步数就是n+m-1。所以答案就是C(n+m-1,n-1),n+m-2步中挑其中n-1步向右。本题数据较大,不可以通过单纯求组合数的公式(杨辉三角或者单个暴力)或者dp。从组合数公式入手,由于除法不可取余,需要求逆元。根据费马小定理有:a和n互质,那么a^(n-1)=1(mod n)。所以a*a^(n-2)=1%(mod n),即a的逆元就是a^(n-2)。

代码:

#include<set>#include<map>#include<stack>#include<queue>#include<vector>#include<string>#include<bitset>#include<algorithm>#include<cstring>#include<cstdio>#include<cmath>#include<ctime>#include<iomanip>#include<iostream>#define debug cout<<"aaa"<<endl#define d(a) cout<<a<<endl#define mem(a,b) memset(a,b,sizeof(a))#define LL long long#define lson l,mid,root<<1#define rson mid+1,r,root<<1|1#define MIN_INT (-2147483647-1)#define MAX_INT 2147483647#define MAX_LL 9223372036854775807i64#define MIN_LL (-9223372036854775807i64-1)using namespace std;const int N = 100000 + 5;const LL mod = 1000000000 + 7;const double eps = 1e-8;LL quick(LL a,LL b){LL ans=1;while(b){if(b&1){ans=(ans*a)%mod;}a=(a*a)%mod; b>>=1;}return ans;}LL F(LL x){LL ans=1;for(LL i=2;i<=x;i++){ans=(ans*i)%mod;}return ans;}int main(){//C(n+m-2,n-1)LL n,m,ans;scanf("%lld%lld",&n,&m);ans=F(n+m-2);ans=(ans*quick(F(n-1),mod-2))%mod;ans=(ans*quick(F(m-1),mod-2))%mod;ans=(ans+mod)%mod;printf("%lld\n",ans); return 0;}


原创粉丝点击