zoukankan      html  css  js  c++  java
  • 【Gym 100947E】Qwerty78 Trip(组合数取模/费马小定理)

    从(1,1)到(n,m),每次向右或向下走一步,,不能经过(x,y),求走的方案数取模。
    可以经过(x,y)则相当于m+n步里面选n步必须向下走,方案数为

    C((m1)+(n1)n1)


    再考虑其中经过(x,y)的方案数,也就是(1,1)到(x,y)的方案乘上(x,y)到(n,m)的方案,为

    C((x1)+(y1),x1)×C((nx)+(my),nx)


    于是答案就是下式取模

    C(m+n2n1)C(x+y2,x1)×C(nx+my,nx)


    m和n大到10的五次方,而组合数要用除法,所以要用费马小定理来求逆元。简单的说就是

    C(n,m)%M=n!%M×(m!)1%M×[(nm)!]1%M

    而逆元用费马小定理和快速幂来算

    (m!)1=qpow(m!,M2)

    最后减法取模记得要再加M再取一次模。

    #include<bits/stdc++.h>
    #define N 200005
    #define M 1000000007
    #define ll long long
    using namespace std;
    ll n,m,t,x,y,fac[N]= {1};
    ll qpow(ll a,ll b)
    {
        ll ans=1;
        ll k=a;
        while(b)
        {
            if(b&1)ans=ans*k%M;
            k=k*k%M;
            b>>=1;
        }
        return ans;
    }
    ll C(ll n,ll m)
    {
        if(m>n)return 0;
        return fac[n]*qpow(fac[m],M-2)%M*qpow(fac[n-m],M-2)%M;
    }
    int main()
    {
        for(int i=1; i<N; i++)fac[i]=fac[i-1]*i%M;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d%d",&n,&m,&x,&y);
            printf("%lld
    ",((C(n+m-2,n-1)-C(x+y-2,x-1)*C(n-x+m-y,n-x)%M+M)%M));
        }
        return 0;
    }

      

  • 相关阅读:
    3个同一行div的摆放div
    Android 项目开发
    iOS 8
    iOS 8
    __FILE__ 与 $_SERVER['SCRIPT_FILENAME']的区别
    高德百度坐标系转换方法
    高德百度坐标系转换方法
    在iOS开发中使用icon font的方法
    在iOS开发中使用icon font的方法
    UIView的setNeedsLayout, layoutIfNeeded 和 layoutSubviews 方法之间的关系解释
  • 原文地址:https://www.cnblogs.com/flipped/p/5646018.html
Copyright © 2011-2022 走看看