思路:
除了左下右上的黑线(障碍物)外,
黑色线为第一部分。
黄色线为第二部分。
用组合数计算加和即可。
Code:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const LL MOD = 1e9+7;
const int AX = 3e5+6;
LL fac[AX] ;
LL inv[AX] ;
LL quick( LL a, LL b ){
LL ans = 1LL;
while( b ){
if( b & 1 ) ans = ( ans * a ) % MOD;
b >>= 1 ;
a = ( a * a ) % MOD;
}
return ans % MOD ;
}
void init(){
fac[0] = 1LL ;
inv[0] = quick( 1 , MOD - 2 ) ;
for( LL i = 1 ; i <= 200005 ; i++ ){
fac[i] = 1LL * fac[i-1] * i % MOD ;
inv[i] = quick( fac[i] , MOD - 2 ) ;
}
}
LL c(LL m,LL n){
if( m < 0 ) return 0 ;
if( n < 0 ) return 0 ;
if( !m ) return 1 ;
//LL res = fac[n] * inv(fac[n-m],MOD) % MOD * inv(fac[m],MOD) % MOD ;
LL res = 1LL * fac[n] * inv[n-m] % MOD * inv[m] % MOD ;
return res % MOD ;
}
int main(){
LL N,M,A,B,C,D;
int T ;
scanf("%d",&T);
init() ;
while( T-- ){
scanf("%lld%lld%lld%lld%lld%lld",&N,&M,&A,&B,&C,&D);
LL cnt = 0LL ;
A = N - A + 1 ;
D = M - D + 1 ;
for( int i = 1 ; i <= M - B - D ; i++ ){
cnt = ( cnt + c( C - 1 , C + B + i - 2 ) * c( N - C - 1 , N - C + M - B - i - 1 ) % MOD ) % MOD ;
}
for( int i = C + 1 ; i <= N - A ; i++ ){
LL tmp = c( B - 1 , i + B - 2 ) % MOD ;
/*if( i <= C ){
for( int j = 1 ; j <= M - B - D ; j++ ){
cnt = ( cnt + tmp * c( C - i , C - i + j - 1 ) % MOD * c( N - C - 1 , N - C + M - B - j - 1 ) % MOD )%MOD;
}
}else{*/ // 用注释里面的也可以但是会TLE
cnt = ( cnt + tmp * c( N - i , N - i + M - 1 - B ) % MOD ) % MOD;
//}
}
printf("%lld\n",cnt);
}
return 0;
}