洛谷P2265 路边的水沟

题目

题目背景

LYQ市有一个巨大的水沟网络,可以近似看成一个n*m的矩形网格,网格的每个格点都安装了闸门,我们将从水沟网络右下角的闸门到左上角的闸门的一条路径称为水流。

题目描述

现给定水沟网的长和宽,求该水沟网中所有只包含向左和向上移动的水流数量。

输入输出格式

输入格式:

输入共1行,包含两个整数n和m。

输出格式:

输出一个数字ans,即水流的数量。由于答案可能很大,请输出答案对1000000007取模的结果。

分析:

由题意推理得:

Cn+mn=(n+m)!n!m!C^{n}_{n+m}=\frac{(n+m)!}{n!m!}Cn+mn=n!m!(n+m)!

但是我们看一下数据范围:n,m&lt;=1000000n,m&lt;=1000000n,m<=1000000

妈呀,这样咋除呀。

这个时候我们就要引入一个东东:

乘法逆元

说白了一个数的乘法逆元就是他的倒数。。。

其他百度一下就行。

用乘法逆元有啥好处?

ans:可以再弄个费马小定理后用快速幂迅速解决。

那么快速幂是啥?

就比如说39=38∗3=322∗3∗343^9=3^8*3={3^2}^2*3*3^439=383=322334等等减少运算次数的,仍可百度。

那么主要思路就出来了:把推出的那个Cn+mn=(n+m)!n!m!C^{n}_{n+m}=\frac{(n+m)!}{n!m!}Cn+mn=n!m!(n+m)!的除号下面的部分转换为他的逆元,通过费马小定理写出幂的形式,然后用快速幂迅速求出。

上代码

代码:

#include<cstdio>
const int mod=1000000007;
long long f(long long n) //计算一波阶乘 
{
    long long sum=1;
    for(long long i=1;i<=n;i++) 
	sum=sum*i%mod;
    return sum;
}
long long pow(long long n,long long p)//快速幂 
{
    if(!p)//a^0=1 (a!=0) 
 		return 1;
    long long tmp=pow(n,p>>1)%mod;
    if(p&1) //即判断是否p%2==1 
		return tmp*tmp%mod*n%mod;
    else 
		return tmp*tmp%mod;
}
long long inv(long long x) 
{ 
    return pow(x,mod-2);//取其逆元,费马小定理 
}
int main() 
{
    int n,m;
    scanf("%d%d",&n,&m);
    printf("%d",(int)(f(n+m)*inv(f(n))%mod*inv(f(m))%mod));//计算公式: 
    return 0;
}

求关注

全部评论

相关推荐

05-23 20:31
已编辑
武汉大学 Java
内向的柠檬精在研究求职打法:注意把武大标粗标大 本地你俩不是乱杀
点赞 评论 收藏
分享
好久没来牛客了,今天面试了一个实习生,感觉对方形象乱糟糟的,头发像鸡窝,像刚睡醒就来面试了,第一印象直接大打折扣,感觉我没有受到应有的尊重,再加上对方业务能力也一般,我直接挂掉;大家面试的时候还是好好收拾一下自己吧,争取给面试官留下个好印象,面试这东西还是存在眼缘的
MinJerous:更在乎本质,应该看候选人是否和岗位需要的能力匹配。洗脸/不洗头都无所谓吧,说不定人家刚刚通宵准备,就是为了这场面试呢?你挂掉他核心原因还是他能力不行,而不是形象。就算形象好点,能力不行你敢给过吗,不怕后面+1质疑你
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务