1. 程式人生 > 其它 >[ARC058B]Iroha and a Grid

[ARC058B]Iroha and a Grid

$\mathcal O(1)$ 我不會,但是我至少會 $\mathcal O(n)$ 的,那就這樣吧。

壹、題目描述 ¶

傳送門 to Luogu.

貳、題解 ¶

唯一限制條件:當 \(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;
}