洛谷P2265 路边的水沟

题目

题目背景

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

题目描述

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

输入输出格式

输入格式:

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

输出格式:

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

分析:

由题意推理得:

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

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

妈呀,这样咋除呀。

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

乘法逆元

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

其他百度一下就行。

用乘法逆元有啥好处?

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

那么快速幂是啥?

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

那么主要思路就出来了:把推出的那个 C n + m n = ( 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;
}

求关注

全部评论

相关推荐

不愿透露姓名的神秘牛友
11-26 16:06
已编辑
快手电商 后端 23k-35k
点赞 评论 收藏
分享
一个菜鸡罢了:哥们,感觉你的简历还是有点问题的,我提几点建议,看看能不能提供一点帮助 1. ”新余学院“别加粗,课程不清楚是否有必要写,感觉版面不如拿来写一下做过的事情,教育经历是你的弱势就尽量少写 2. “干部及社团经历”和“自我评价”删掉 3. 论文后面的“录用”和“小修”啥的都删掉,默认全录用,问了再说,反正小修毕业前肯定能发出来 4. 工作经验和研究成果没有体现你的个人贡献,着重包装一下个人贡献
点赞 评论 收藏
分享
美丽的查理斯不讲武德:包kpi的啊,感觉虾皮一点hc都没有
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务