HihoCoder 1480:矩阵填数 (杨氏矩阵 || 钩子公式 + 筛逆元)
描述
小Hi在玩一个游戏,他需要把1, 2, 3, ... NM填入一个N行M列的矩阵中,使得矩阵每一行从左到右、每一列从上到下都是递增的。
例如如下是3x3的一种填法:
136 247 589
给定N和M,小Hi希望知道一共有多少种不同的填法。
输入
一行包含两个整数N和M。
对于60%的数据 1 <= N <= 2, 1 <= M <= 100000
对于20%的数据 N = 3, 1 <= M <= 100
对于100%的数据 1 <= N <= 3, 1 <= M <= 100000
输出
输出一共有多少种不同的填法。由于结果可能很大,你只需输出答案模109+7的余数。
样例输入
3 2
样例输出
5
第5页的hihocoder基本是刷完了,回去刷第4页,妈蛋,整体上难好多啊。
此题是裸的钩子公式,也有人用三维的卡特兰数做的。
具体的可以参考:http://www.cnblogs.com/hua-dong/p/8454215.html
#include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; #define ll long long const int maxn=300010; const int Mod=1e9+7; ll rev[maxn],fac[maxn],n,m,ans; void prepare() { fac[0]=1; rev[1]=1; for(int i=1;i<=n*m;i++){ fac[i]=fac[i-1]*i%Mod; } for(int i=2;i<=n*m;i++) rev[i]=(Mod-Mod/i)*rev[Mod%i]%Mod; } int main() { scanf("%lld%lld",&n,&m); prepare(); ans=fac[n*m]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ ans=ans*rev[i+j-1]%Mod; } printf("%lld\n",ans); return 0; }
It is your time to fight!