Hopscotch

Hopscotch

Time Limit: 5 Sec Memory Limit: 128 MB

Topic description

You’re playing hopscotch! You start at the origin and your goal is to hop to the lattice point (N, N). A hop consists of going from lattice point (x1, y1) to (x2, y2), where x1 < x2 and y1 < y2.
You dislike making small hops though. You’ve decided that for every hop you make between two lattice points, the x-coordinate must increase by at least X and the y-coordinate must increase by at least Y .
Compute the number of distinct paths you can take between (0, 0) and (N, N) that respect the above constraints. Two paths are distinct if there is some lattice point that you visit in one path which you don’t visit in the other.
Hint: The output involves arithmetic mod 109+ 7. Note that with p a prime like \(10^9+ 7\), and x an integer not equal to 0 mod p, then \(x(x^p−2)\) mod \(p\) equals 1 mod p.

enter

The input consists of a line of three integers, N X Y . You may assume 1 ≤ X, Y ≤ N ≤ \(10^6\).

output

The number of distinct paths you can take between the two lattice points can be very large. Hence output this number modulo 1 000 000 007 \((10^9+ 7)\).

sample input

7 2 3

Sample output

9

meaning of the title

From the coordinates \((0,0)\) to \((n,n)\) , each step takes at least X steps in the horizontal direction and Y steps in the vertical direction. Ask how many ways to get to the point

analyze

Consider the number of ways to take i steps to the end point, which is equal to the product of the number of ways to go from the horizontal and vertical directions to the coordinate n.
Taking the horizontal direction as an example, use \(dp[i]\) to represent the number of ways to go from \(x=0\) to \(x=n\) exactly i steps. This is actually equivalent to the question: assign n identical balls to i different people, each with at least X balls, and ask how many ways there are.
You can first divide \(X-1\) balls for each person, and then there are remaining \(n-(X-1) \times i\) balls. For the remaining balls, use the partition method, and the number of ball distribution methods is \(C_{n-(X-1)\times i}^{i-1}\) ;
the final result is \[ \sum_{i=1}^{ min(\frac{n}{X},\ frac{n}{Y}) } C_{n-(X-1)\times i}^{i-1} C_{n-(Y-1)\times i}^{i-1}\]

code

#include <cstdio>
#include <vector>
#include <algorithm>
#include <iostream>
typedef long long ll;
using namespace std;
ll mod = 1000000007;
const int maxn = 1000010;
 
ll qpow(ll a,ll x){
    ll ret=1;
    while (x){
        if (x&1)
            ret = ret*a%mod;
        a=a*a%mod;
        x>>=1;
    }
    return ret;
}
ll fac[maxn],inv[maxn];
 
ll init(){
    fac[0]=1;
    for (int i=1;i<maxn;i++)
        fac[i]=fac[i-1]*i%mod;
    inv[maxn-1]=qpow(fac[maxn-1],mod-2);
    for (int i=maxn-2;i>=0;i--)
        inv[i]=inv[i+1]*(i+1)%mod;
    return 0;
}
 
ll c(ll n,ll m){
    if (n<m) return 0;
    return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
 
ll dp1[maxn],dp2[maxn];
 
 
int main() {
    init();
    ll n,x,y;
    scanf("%lld%lld%lld",&n,&x,&y);

    for (int i=1;i*x<=n;i++)
    {
        dp1[i]=c(n-(x-1)*i-1,i-1);
    }
 
    for (int i=1;i*y<=n;i++)
    {
        dp2[i]=c(n-(y-1)*i-1,i-1);
    }
 
    ll ans = 0;
    for (int i=1;i*x<=n&&i*y<=n;i++)
        ans =( ans + dp1[i]*dp2[i]%mod)%mod ;
 
    printf("%lld\n",ans);
 
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324634845&siteId=291194637