[ARC058B]Iroha and a Grid
阿新 • • 發佈:2021-07-28
$\mathcal O(1)$ 我不會,但是我至少會 $\mathcal O(n)$ 的,那就這樣吧。
壹、題目描述 ¶
貳、題解 ¶
唯一限制條件:當 \(i\le A\) 時,\(j\le B\). 問方案數。
想到一種方案,我們可以用圖上的方法來求:
簡而言之,我們列舉豎著走了 \(N-A-2\) 步之後,橫著走了多少步,但是必須保證橫著走的步數大於等於 \(B\),然後把兩種方案乘起來即可。
叄、參考程式碼 ¶
#include<cstdio> #include<algorithm> #include<vector> #include<cstring> using namespace std; #define NDUBUG #include<cassert> namespace Elaina{ #define rep(i, l, r) for(int i=(l), i##_end_=(r); i<=i##_end_; ++i) #define drep(i, l, r) for(int i=(l), i##_end_=(r); i>=i##_end_; --i) #define fi first #define se second #define mp(a, b) make_pair(a, b) #define Endl putchar('\n') #define mmset(a, b) memset(a, b, sizeof a) // #define int long long typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; typedef pair<ll, ll> pll; template<class T>inline T fab(T x){ return x<0? -x: x; } template<class T>inline void getmin(T& x, const T rhs){ x=min(x, rhs); } template<class T>inline void getmax(T& x, const T rhs){ x=max(x, rhs); } template<class T>inline T readin(T x){ x=0; int f=0; char c; while((c=getchar())<'0' || '9'<c) if(c=='-') f=1; for(x=(c^48); '0'<=(c=getchar()) && c<='9'; x=(x<<1)+(x<<3)+(c^48)); return f? -x: x; } template<class T>inline void writc(T x, char s='\n'){ static int fwri_sta[1005], fwri_ed=0; if(x<0) putchar('-'), x=-x; do fwri_sta[++fwri_ed]=x%10, x/=10; while(x); while(putchar(fwri_sta[fwri_ed--]^48), fwri_ed); putchar(s); } } using namespace Elaina; const int maxn=1e5; const int mod=1e9+7; inline int qkpow(int a, int n){ int ret=1; for(; n>0; n>>=1, a=1ll*a*a%mod) if(n&1) ret=1ll*ret*a%mod; return ret; } int fac[maxn*2+5], finv[maxn*2+5]; inline void prelude(){ fac[0]=1; for(int i=1; i<=maxn*2; ++i) fac[i]=1ll*fac[i-1]*i%mod; finv[maxn*2]=qkpow(fac[maxn*2], mod-2); for(int i=maxn*2-1; i>=1; --i) finv[i]=1ll*finv[i+1]*(i+1)%mod; finv[0]=1; } inline int C(int n, int m){ if(n<m) return 0; return 1ll*fac[n]*finv[m]%mod*finv[n-m]%mod; } int n, m, a, b, ans; signed main(){ prelude(); n=readin(1), m=readin(1), a=readin(1), b=readin(1); for(int i=b+1; i<=m; ++i){ int fron=C((n-a-1)+(i-1), i-1); int step=a-1+m-i; int lst=C(step, a-1); ans=(ans+1ll*fron*lst%mod)%mod; } writc(ans); return 0; }