hdu5698 組合數學(求組合數)
阿新 • • 發佈:2019-02-03
這題真的是有點煩人。
首先可以想到相當於是在左上角區域內選0到min(m-2,n-2)個點,然後求和。
(假設m<=n)也就是
雖然這樣已經可以AC了,但是這個式子是可以化簡的。
要用到這樣一個性質:
證明如下:
首先知道,C(m-1,n)+C(m-1,n-1)=C(m,n),
然後:
套用這個性質,我們就可以得到答案就是C(m+n-4,m-2);
不過得到這個之後我就寫了個分解素因數算了個組合數,然後就很糟心地TLE了.
正兒八經地寫個逆元就不會T:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e5+5;
const int mo=1e9+7;
long long jie[2*maxn];
int n,m;
long long Pow(long long a,int b)
{
long long ans=1;
while(b)
{
if(b&1) ans=ans*a%mo;
a=a*a%mo;
b>>=1;
}
return ans;
}
void init()
{
jie[0]=1;
for (int i=1;i<2*maxn;i++) jie[i]=jie[i-1]*i%mo;
}
long long cal(long long a,long long b)
{
int temp=(jie[b]*jie[a-b])%mo;
return (jie[a]*Pow(temp,mo-2))%mo;
}
int main()
{
init();
scanf("%d%d",&n,&m);
long long ans=cal(n+m-4,n-2);
printf("%lld\n",ans);
return 0;
}