abc145D 騎士走棋盤到達目的地的方案數

chenfy27發表於2024-03-10

有一張二維棋盤,騎士每次可以從(i,j)移到(i+1,j+2)或(i+2,j+1)。求騎士從位置(0,0)移到(X,Y)的路徑方案數?結果對1E9+7取模。
1<=X,Y<=1E6

dp的時間複雜度為O(XY),會TLE,因此考慮數學方法。假設走法1用了A次,走法2用了B次,那麼有A+2B=X,並且2A+B=Y,可以算出A和B,答案就是C(A+B,A)。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a; i<=b; i++)
#define per(i,a,b) for(int i=b; i>=a; i--)

template<int MOD>
struct MInt {
    int x;
    int norm(int u) const {u%=MOD; if(u<0) u+=MOD; return u;}
    MInt(int v=0):x(norm(v)) {}
    int val() const {return x;}
    MInt operator-() const {return MInt(norm(MOD-x));}
    MInt inv() const {assert(x!=0); return qpow(MOD-2);}
    MInt &operator*=(const MInt &o) {x=norm(x*o.x); return *this;}
    MInt &operator+=(const MInt &o) {x=norm(x+o.x); return *this;}
    MInt &operator-=(const MInt &o) {x=norm(x-o.x); return *this;}
    MInt &operator/=(const MInt &o) {*this *= o.inv(); return *this;}
    friend MInt operator*(const MInt &a, const MInt &b) {MInt ans=a; ans*=b; return ans;}
    friend MInt operator+(const MInt &a, const MInt &b) {MInt ans=a; ans+=b; return ans;}
    friend MInt operator-(const MInt &a, const MInt &b) {MInt ans=a; ans-=b; return ans;}
    friend MInt operator/(const MInt &a, const MInt &b) {MInt ans=a; ans/=b; return ans;}
    friend std::istream &operator>>(std::istream &is, MInt &a) {int u; is>>u; a=MInt(u); return is;}
    friend std::ostream &operator<<(std::ostream &os, const MInt &a) {os<<a.val(); return os;}
    MInt qpow(int b) const {int r=1, t=x; while(b){if(b&1) r=r*t%MOD; t=t*t%MOD; b/=2;} return MInt(r);}
};
using mint = MInt<1000000007>;

int X, Y;
mint comb(int n, int k) {
    mint r = 1;
    rep(i,1,k) r *= n-i+1;
    rep(i,1,k) r /= i;
    return r;
}
void solve() {
    cin >> X >> Y;
    if (2*X < Y || (2*X-Y) % 3 != 0) {
        cout << 0 << "\n";
        return;
    }
    if (2*Y < X || (2*Y-X) % 3 != 0) {
        cout << 0 << "\n";
        return;
    }
    int A = (2*X-Y) / 3;
    int B = (2*Y-X) / 3;
    cout << comb(A+B, A) << "\n";
}

signed main() {
    cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

相關文章