# 14th SWJTUCPC Warming Up A chess Problem 【easy】【medium】【hard】【组合数 + lucas】

### 描述

In chinese chess, “马” is an interesting piece, when it is at position$\left(x,y\right)$$(x,y)$, it can move to$\left(x-2,y-1\right),\left(x-2,y+1\right),\left(x-1,y-2\right),\left(x-1,y+2\right),\left(x+1,y-2\right),\left(x+1,y+2\right),\left(x+2,y-1\right),\left(x+2,y+1\right)$$(x−2,y−1),(x−2,y+1),(x−1,y−2),(x−1,y+2),(x+1,y−2),(x+1,y+2),(x+2,y−1),(x+2,y+1)$,

Now the problem is, when a “马” is at position (x,y), how many ways does it have for he to move to $\left(x0,y0\right).$$(x0,y0).$

To simplify this problem, when our “马” is at (x,y), it can only move to$\left(x+1,y+2\right)or\left(x+2,y+1\right)$$(x+1,y+2) or (x+2,y+1)$

### easy输入

The first line: the number of case T(≤T≤100)
Then T lines follow, each line contains four integers: x,y,x0,y0(0≤x,y,x0,y0≤8) - the position the “马” at and the position it want’s to go.

### easy输出

For each case, out put an integer ans one line – the number of the ways to go from (x,y) to (x0,y0)

### medium输入

The first line: the number of case T(≤T≤1000)
Then T lines follow, each line contains four integers: x,y,x0,y0(0≤x,y,x0,y0≤100000) - the position the “马” at and the position it want’s to go.

### medium输出

For each case, out put an integer ans one line – the number of the ways to go from (x,y) to (x0,y0) mod 109+7

### hard输入

The first line: the number of case T(≤T≤1000)
Then T lines follow, each line contains four integers: x,y,x0,y0(0≤x,y,x0,y0≤10000000) - the position the “马” at and the position it want’s to go.

### hard输出

For each case, out put an integer ans one line – the number of the ways to go from (x,y) to (x0,y0) mod 104+7

3
0 0 3 3
0 0 6 6
3 3 6 6

2
6
2

### 提示

In the first example:

(0,0)−>(2,1)−>(3,3),(0,0)−>(1,2)−>(3,3)
In the second example:

(0,0)−>(2,1)−>(4,2)−>(5,4)−>(6,6),(0,0)−>(2,1)−>(3,3)−>(5,4)−>(6,6)
(0,0)−>(2,1)−>(3,3)−>(4,5)−>(6,6),(0,0)−>(1,2)−>(3,3)−>(5,4)−>(6,6)
(0,0)−>(1,2)−>(3,3)−>(4,5)−>(6,6),(0,0)−>(1,2)−>(2,4)−>(4,5)−>(6,6)
In the third example:

(3,3)−>(5,4)−>(6,6),(3,3)−>(4,5)−>(6,6)

，我们找到此规律后就好办了，首先是medium，直接预处理出1e5的阶乘（取模后），然后有图找到相应的${C}_{n}^{k}$$C_n^k$即可，hard里我们利用Lucas可以快速求大整数取模，详见代码

### 参考代码

// medium

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
const int maxn = 1e5 + 10;

const int MOD = 1e9 + 7;
typedef long long ll;

#define mod(x) ((x) % MOD)

ll qpow(ll a,ll b) {
ll res = 1;
while (b) {
if(b & 1) {
res = mod(res * a);
}
a = mod(a * a);
b >>= 1;
}
return res;
}
ll x,y,xx,yy;
ll fac[maxn], rfac[maxn];

void init() {
fac[0] = 1;
for (int i = 1; i <= maxn; i++)
fac[i] = mod(fac[i - 1] * i);
rfac[maxn] = qpow(fac[maxn],MOD - 2);
for (int i = maxn;i > 0; i--)
rfac[i - 1] = mod(rfac[i] * i);
}
int main(){
int T; cin>>T;
init();
while (T--) {
cin>>x>>y>>xx>>yy;
ll ex = xx - x;
ll ey = yy - y;
if(ex <= 0 || ey <= 0 || (ex + ey) % 3 != 0) {
puts("0");
} else {
ll t = (ex + ey) / 3;
ll bo = t;
ll up = t + t;
if(ey < bo || ey > up) {
puts("0");
} else {
ll k = ey - t;
ll n = t;
cout<<mod(fac[n] * 1ll*mod(rfac[k]*1ll*rfac[n - k]))<<endl;
}
}
}
return 0;
}

### 参考代码

// hard
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
const int maxn = 1e5 + 7;

const int MOD = 1e4 + 7;
typedef long long ll;

#define mod(x) ((x) % MOD)

ll qpow(ll a,ll b) {
ll res = 1;
while (b) {
if(b & 1) {
res = mod(res * a);
}
a = mod(a * a);
b >>= 1;
}
return res;
}

ll x,y,xx,yy;

ll C(ll nn, ll mm) {
ll up = 1, down = 1;
for (int i = nn - mm + 1; i <= nn; i++) up = mod(up * 1ll *i);
for (int i = 1; i <= mm; i++) down = mod(down * 1ll *i);
return mod(up * qpow(down, MOD - 2));
}

ll lucas(ll n, ll m) {
if(m == 0) return 1;
return mod(lucas(n / MOD, m / MOD) * 1ll * C(n % MOD,m % MOD));
}

int main(){
int T; cin>>T;
while (T--) {
cin>>x>>y>>xx>>yy;
ll ex = xx - x;
ll ey = yy - y;
if(ex <= 0 || ey <= 0 || (ex + ey) % 3 != 0) {
puts("0");
} else {
ll t = (ex + ey) / 3;
ll bo = t;
ll up = t + t;
if(ey < bo || ey > up) {
puts("0");
} else {

ll k = ey - t;
ll n = t;
cout<<lucas(n,k)<<endl;
}
}
}
return 0;
}