topic
Cults like to jump in all kinds of spaces. Now, the cult has come to a two-dimensional plane.
In this plane, if the cult currently jumps to (x,y), then he can choose to jump to the following 4 points in the next step:
(x-1,y),(x+1,y),(x,y- 1), (x, y+1).
And whenever the cult reaches a point, he needs to consume some physical strength,
assuming that the physical strength required to reach (x, y) is represented by C(x, y).
For C(x,y), there are the following properties:
1. If x=0 or y=0, then C(x,y)=1.
2. If x>0 and y>0, then C(x,y)=C(x,y-1)+C(x-1,y).
3. If x<0 and y<0, then C(x,y)=infinity.
Now, the cult wants to know how much stamina it takes to start from (0,0) to (N,M), and the stamina
to get to (0,0) also needs to be counted).
Since the answer may be large, just output the answer modulo 10^9+7.
input format
Read in two integers N, M, representing the point the cult wants to reach.
0<=N, M<=10^12 , N*M<=10^12
output format
The output is only an integer, which represents the result of modulo 10^9+7 by the minimum physical effort that the cult needs to spend.
input sample
1 2
Sample output
6
answer
Draw a picture and find that it is a Yanghui triangle
First make \(M \le N\)
we have to go to \({N + M \choose M}\)
greedy path is to go first \(N + 1\) \ (1\) , and then go diagonally \(M\) step
Try to change the path and find that there is no problem with such greed
The answer is
\[N + \sum\limits_{i = 0}^{M} {N + i \choose i}\]
The number of combinations has a more commonly used conclusion is
\[\sum\limits_{i = 0}^ {M} {N + i \choose i} = {N + M + 1 \choose M}\]
It can be proved by recursion of combinatorial numbers
Then the answer is
\[N + {N + M + 1 \choose M}\]
Since the title has the limitation of \(N*M \le 10^{12}\) , so \(M \le 10^6\) , just calculate
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000,P = 1e9 + 7;
LL N,M;
LL qpow(LL a,LL b){
LL ans = 1;
for (; b; b >>= 1,a = a * a % P)
if (b & 1) ans = ans * a % P;
return ans;
}
int main(){
scanf("%lld%lld",&N,&M);
if (M > N) swap(N,M);
LL ans = 1,ansb = 1;
for (LL i = 1; i <= M; i++){
ans = ans * ((N + M + 2 - i + P) % P) % P;
ansb = ansb * i % P;
}
ans = ((ans * qpow(ansb,P - 2) % P + N) % P + P) % P;
printf("%lld\n",ans);
return 0;
}