#include #include using namespace std; const long long MOD = 1000000007; // 繰り返し二乗法 long long power(long long base, long long exp) { long long res = 1; base %= MOD; while (exp > 0) { if (exp % 2 == 1) res = (res * base) % MOD; base = (base * base) % MOD; exp /= 2; } return res; } // フェルマーの小定理による逆元 long long modInverse(long long n) { return power(n, MOD - 2); } void solve() { string C_str, P_str; if (!(cin >> C_str >> P_str)) return; // 足切り1: P >= MOD // 文字列が11桁以上なら確実に 10^9+7 を超えている if (P_str.length() > 10) { cout << 0 << "\n"; return; } long long P = stoll(P_str); if (P >= MOD) { cout << 0 << "\n"; return; } // 足切り2: C < 2P - 1 // P < MOD より 2P-1 は高々 2*10^9+13。Cが12桁以上なら余裕で満たす if (C_str.length() <= 11) { long long C = stoll(C_str); if (C < 2 * P - 1) { cout << 0 << "\n"; return; } } // C mod M を文字列から O(|C|) で計算 long long C_mod = 0; for (char c : C_str) { C_mod = (C_mod * 10 + (c - '0')) % MOD; } // N mod M の計算 long long n0 = (C_mod - P + 1) % MOD; if (n0 < 0) n0 += MOD; // 足切り3: n_mod < P if (n0 < P) { cout << 0 << "\n"; return; } long long ans = 1; // 最適化: O(min(P, MOD-P)) で階乗の割り算を処理 if (P <= MOD / 2) { // P が小さい場合は愚直に P 回掛ける for (long long i = 0; i < P; i++) { ans = (ans * (n0 - i)) % MOD; } } else { // P が大きい場合はウィルソンの定理を利用し、M-P 回の掛け算に抑える long long denom1 = 1; for (long long i = n0 + 1; i < MOD; i++) { denom1 = (denom1 * i) % MOD; } long long denom2 = 1; for (long long i = 1; i <= n0 - P; i++) { denom2 = (denom2 * i) % MOD; } long long denom = (denom1 * denom2) % MOD; ans = (MOD - 1) * modInverse(denom) % MOD; // -1 * (denom^-1) } cout << ans << "\n"; } int main() { // 入出力の高速化 ios_base::sync_with_stdio(false); cin.tie(NULL); int T; if (cin >> T) { while (T--) solve(); } return 0; }