NC206842. Walk
描述
输入描述
第一行输入一个正整数 T,代表询问次数 (1 ≤ T ≤ 100000)接下来 T 行,每行输入两个正整数 N,M (1 ≤ N ≤ 106,1 ≤ M ≤ 106)
输出描述
对于每次询问,输出一个正整数,代表在行走步数最少的情况下,从(1, 1)点走到(N, M)点的方法总数 (答案可能过大,请对答案取模1000000007)
示例1
输入:
1 2 2
输出:
2
说明:
示例2
输入:
1 2 3
输出:
3
说明:
示例3
输入:
1 5 3
输出:
15
C++14(g++5.4) 解法, 执行用时: 221ms, 内存消耗: 18520K, 提交时间: 2020-06-25 00:12:51
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=1000000007; const int maxn=2e6+10; ll f[maxn]; ll fpow(ll a,ll b){ ll ans=1; while(b){ if(b&1) ans=(ans*a)%mod; b/=2;a=(a*a)%mod; } return ans%mod; } void init(){ f[0]=1;f[1]=1; for(int i=2;i<maxn;i++) f[i]=(f[i-1]*i)%mod; } int main() { init(); int t; cin>>t; while(t--){ ll n,m; scanf("%lld%lld",&n,&m); cout<<(f[n+m-2]*fpow((f[n-1]*f[m-1])%mod,mod-2))%mod<<endl; } return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 284ms, 内存消耗: 17016K, 提交时间: 2020-06-14 14:25:46
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1e6+10; const int mod=1000000007; ll n,m,fac[maxn*2],x,y; void exgcd(ll a,ll b,ll &x,ll &y){ if(!b) x=1,y=0; else exgcd(b,a%b,y,x),y-=a/b*x; } int main() { fac[0]=1; for(ll i=1;i<=2000000;i++) fac[i]=fac[i-1]*i%mod; int t; cin>>t; while(t--) { cin>>n>>m; ll temp=fac[n-1]*fac[m-1]; exgcd(temp,mod,x,y); x=(x%mod+mod)%mod; cout<<x*fac[n+m-2]%mod<<endl; } }