[Noip2011]计算系数

Sol1:利用杨辉三角求C(N,M).坐标从 (0,0)开始,则第n行第m列就是C(N,M)

#include<bits/stdc++.h>
#define s 1100
using namespace std;
int x[s][s];
main()
{
    int a,b,k,n,m;
    x[0][0]=1;
    scanf("%d%d%d%d%d",&a,&b,&k,&n,&m);
    a%=10007;
    b%=10007;
    for(int i=1;i<=k;i++)
       for(int j=0;j<=i;j++)
    	x[i][j]=(x[i-1][j]+x[i-1][j-1])%10007;}
    
    int product=x[k][n];
    for(int i=1;i<=n;i++)product=product*a%10007;
    for(int i=1;i<=m;i++)product=product*b%10007;
    printf("%d",product);
    return 0;
}

  

Sol2:

直接算组合数C(N,M)=分子/分母,然后在取模的时候,求出分母这一个数字针对P的逆元即可。

当然也可以在计算过程中,算出1到m每个数字针对P的逆元。转化成N*(N-1)*(N-2)*(N-M_1) * 1的逆元 * 2的逆元 * 3的逆元*.....M的逆元

求逆元的几种方法

1:单个数字可以用扩欧来求解

2:1--N之间所有数字,可以递推求解

3:用欧拉定理,直接找出逆元。

#include<bits/stdc++.h>
using namespace std;
const int mod=10007;
long long ksm(long long a,long long b)
{
    if(b==0)return 1;
    if(b%2==0)return ksm(a,b>>1)*ksm(a,b>>1)%mod;
    else return a*ksm(a,b>>1)*ksm(a,b>>1)%mod;
}
int main()
{
    int a,b,k,m,n;
    cin>>a>>b>>k>>n>>m;
    int c=1,d=1;
    for(int i=1;i<=n;i++)
        c=c*i%mod;
    for(int i=k-n+1;i<=k;i++)
        d=d*i%mod;
    d=d*ksm(c,mod-2)%mod;
    d=d*ksm(a,n)*ksm(b,m)%mod;
    cout<<d;
}

  

猜你喜欢

转载自www.cnblogs.com/cutemush/p/12005107.html