A - Will he Die? Gym - 101778A

Unfortunately, Conan is in a real danger! Conan discovered who is the killer after searching for the evidence in a dangerous cave. Now, he is standing in front of a bomb that about to explode. The bomb will explode after m seconds.

The cave is represented as an infinite horizontal line that runs from  - ∞ to ∞, as shown in the picture below:

Initially, Conan stands at position 0. At each second, he will move either one step to the left (i.e. from position y to y - 1) or one step to the right (i.e. from position y to y + 1) with an equal probability (i.e. 0.50). Conan will be safe if he reached position n.

Conan is wondering what is the probability that he will be at position n after m seconds. Can you help Conan in calculating his chances of surviving?

Input

The first line contains an integer T (1 ≤ T ≤ 105), in which T is the number of test cases.

Then T lines follow, each line contains two integers n and m ( - 2 × 105 ≤ n ≤ 2 × 105) (0 ≤ m ≤ 2 × 105), as described in the problem statement.

Output

For each test case, print a single line containing z, in which z is the sought probability computed module 109 + 7.

The answer z is defined precisely as follows. Represent the probability that Conan will be at position n after m seconds as an irreducible fraction p / q. The number z then must satisfy the modular equation , and be between 0 and 109 + 6, inclusive. It can be shown that under the constraints of this problem such a number z always exists and is uniquely determined.

Example

Input

3
0 0
1 1
-3 3

Output

1
500000004
125000001

Note

In the second test case, Conan wants to know what is the probability that he will be at postilion 1 after 1 second of moving. The probability is 1 / 2, and the answer is 500000004, since .

 

第m步走到n点的概率为 C(m, (n + m) / 2) / pow(2, m) ;

其中abs(n) <= m 并且 (n + m) % 2 == 0;

p = C(m, (n + m) / 2);

q = pow(2, m);

z * q % mod == p % mod;

求z;

z * q * inv(q) % mod = p *inv(q) % mod;

z = p * inv(q) % mod;

求逆元可用 费马小定理 + 快速幂 or 扩展欧几里得

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<vector>

using namespace std;
typedef long long LL;
const LL MOD = 1e9 + 7;
const LL maxn =  2 * 1e5 + 10;
LL Jc[200010];

LL f(LL a, LL b){
    LL ans = 1;
    while(b){
        if(b & 1){
            ans *= a;
            ans %= MOD;
        }
        a *= a;
        a %= MOD;
        b /= 2;
    }
    return ans % MOD;
}
LL inv(LL a){
    return f(a, MOD - 2);
}

void calJc()
{
    Jc[0] = Jc[1] = 1;
    for(LL i = 2; i < maxn; i++)
        Jc[i] = Jc[i - 1] * i % MOD;
}

LL C(LL n, LL m){
    if(n < m)return 0;
    return Jc[n] * inv(Jc[m]) % MOD *inv(Jc[n - m]) % MOD;
}
int main(){
  ios::sync_with_stdio(false);
  int t;
  cin >> t;
  calJc();
  while(t--){
    LL n, m;
    cin >> n >> m;

    LL y;
    if(abs(n) % 2 != m % 2 || abs(n) > m){
        cout << 0 << endl;
        continue;
    }
    if(n < 0)n = -n;
    y = (C(m, (n + m) / 2) % MOD * inv(f(2, m)) % MOD) % MOD;
    cout << y << endl;
  }
  return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值