ZOJ - 4006 Travel along the Line

题意:
从原点出发,求n秒后在m点的概率,每一秒有1/4可能向左移一格,1/4可能向右移一格,1/2可能不移动。
T组数据,每一行输入n,m
Sample Input
3
2 -2
0 0
0 1
Sample Output
562500004
1
0

用费马小定理求逆元。

#include"bits/stdc++.h"
using namespace std;
#define LL long long
typedef long long ll;
const int mx = 1e5+5;
const ll mod = 1e9+7;
ll A[mx];
ll B[mx];
ll modexp(ll x,ll n){
    ll ans = 1;
    while(n){
        if(n&1) ans = ans*x%mod;
        x = x*x%mod;
        n /= 2;
    }
    return ans;
}
int main(){
    A[0] = 1;
    int t;
    for(int i = 1; i < mx; i++)
        A[i] = A[i-1]*i%mod;
    B[0] = B[1] = 1;
    for(int i = 1; i < mx; i++)
        B[i] = modexp(A[i],mod-2);
    scanf("%d",&t);
    while(t--){
        int n,m;
        scanf("%d%d",&n,&m);
        m = abs(m);
        if(n<m){
            puts("0");
            continue;
        }
        if(n==m){
            ll ans = modexp(modexp(4,n),mod-2);
            printf("%lld\n",ans);
            continue;
        }
        ll ans = 0;
        for(int i = m; 2*i <= n+m; i++){
            ll sum = modexp(modexp(4,i),mod-2);
               sum = sum*modexp(modexp(4,i-m),mod-2)%mod;
               sum = sum*modexp(modexp(2,n-2*i+m),mod-2)%mod;
               sum = sum*A[n]%mod*B[i]%mod*B[n-i]%mod;
               sum = sum*A[n-i]%mod*B[i-m]%mod*B[n+m-2*i]%mod;
            ans += sum;
            if(ans>=mod)
                ans -= mod;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

你可能感兴趣的:(ZOJ - 4006 Travel along the Line)