Will he Die? Gym - 101778A (排列组合+求逆元)
Problem Description
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 ≤ 1e5), in which T is the number of test cases.
Then T lines follow, each line contains two integers n and m ( - 2 × 1e5 ≤ n ≤ 2 × 1e5) (0 ≤ m ≤ 2 × 1e5), 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 1e9 + 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 1e9 + 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 .
题意
有一个点在一维数轴的原点0位置,每秒你可以选择向左or向右移动1个单位的距离。问在m秒后,刚好在点n的概率是多少(需要取模1e9+7,数轴左负右正)
T组输入(1<=T<=1e5)
每组输入两个整数 N 和 M.(0<=|N|<=2e5,0<=M<=2e5)
思路
一、如果N的绝对值大于M则概率为0 (因为即使所有的M秒都朝一个方向移动,距离也不能超过N的绝对值)
二、M等于N的绝对值,概率为2^M,即每次朝一个固定的方向移动
三、M大于等于N的绝对值,很明显M秒里一定向左和向右都要有,即有回头
比如M=10,N=6,
为了最终到达点 6 ,一定有唯一的向右、向左的移动次数
即:向右移动的次数为8,向左为2
唯一的原因:设向左移动次数为A,向右为B
则 A+B=M and A-B=N,用初中的知识就可以知道两个方程,两个未知数(一次幂)
可以得唯一解,也容易得到只有M-|N|的值为偶数的时候,才有A和B的整数解
即M=10,N=7,没有方案可以使终点为7
K=(M-|N|)/ 2
所以概率为 C(M,K)/ (2^M),可以理解为M次移动中选择K次移动“回头”的方案,在所有移动情况下的概率
C(M,K)=M! / (K!* (M-K)!) //K!为K的阶乘的意思
因为答案为分数,所以不能直接取模,要用逆元
求法:分数a/b % mod
答案=a*inv(b)%Mod;
AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mod=1000000007;
#define maxn 200010
ll p[maxn]; //p[i]为i的阶乘
ll quick(ll x, ll k) //求x^k的快速幂
{
ll ans=1LL;
while(k){
if(k&1){
k--;
ans=(ans*x)%mod;
}
k>>=1;
x=(x*x)%mod;
}
return ans;
}
ll inv(ll x) //用于求逆元
{
return quick(x, mod-2LL);
}
ll C(int m,int n) //求能到达终点的方案数,注意分母放在inv()里
{
return p[m]*inv(p[m-n]*p[n]%mod)%mod;
}
int main()
{
int i;
p[0]=1LL; //为方便0的时候取1
for(i=1;i<=200000;i++){
p[i]=(p[i-1]*i)%mod;
}
int t;
scanf("%d", &t);
while(t--){
int n,m;
scanf("%d %d", &n,&m);
n=abs(n);
if(n>m||(m-n)%2==1){ //没有方案的时候
printf("0\n");
continue;
}
int k=(m-n)/2;
ll ans=C(m,k);
ans=ans*inv(quick(2LL,m))%mod;
printf("%lld\n",ans);
}
return 0;
}