關鍵:
用公式來線性預處理逆元。
#include<bits/stdc++.h>
using namespace std;
const long long int mod = 1e9 + 7;
long long int Rank[200000]; //rank 和系統命名衝突
long long int inv[100001];
long long int invRank[100001];
void init(){
Rank[0] = Rank[1] = 1; //計算階乘
for(int i=2;i<200000;i++){
Rank[i] = (Rank[i-1]*i)%mod;
}
inv[1] = 1;
for(int i=2;i<100000;i++){ //計算逆元
inv[i]=((mod-mod/i)*inv[mod%i])%mod;//or inv[i]=(mod-(mod/i*inv[mod%i])%mod)%mod;
}
invRank[0]=invRank[1]=1;
for(int i=2;i<100000;i++){
invRank[i] = (invRank[i-1]*inv[i])%mod;
}
}
int main(){
int n,m;
init();
while(cin>>n>>m){
// cout<<rank[n+m-2]<<" "<<invRank[n-1]<<" "<<invRank[m-1]<<endl;
cout<<Rank[n+m-2]*invRank[n-1]%mod*invRank[m-1]%mod<<'\n';
}
return 0;
}
參考:
線性求逆元及其過程(有瑕疵,大體思路明確)
代碼參考(寫的很好,思路明確)
錯誤範例:動態規劃——>超時
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAX_N 100001
const int mod = 1e9 + 7;
long long int C[2][MAX_N];
int main() {
int n,m;
while(cin>>n>>m){
for(int t=1;t<=m;t++){
C[0][t] = 1;
}
for(int i =n-1;i>=1;i--){
C[1][m] =1;
for(int j=m-1;j>=1;j--){
C[1][j]=(C[1][j+1]%mod+C[0][j]%mod)%mod;
}
for(int t=1;t<=m;t++){
C[0][t]=C[1][t];
}
}
cout<<C[0][1]<<'\n';
}
return 0;
}