NOIP 2011 計算係數 快速冪+組合數

題目描述

給定一個多項式(by+ax)k ,請求出多項式展開後xnym 項的係數。

輸入格式:

輸入文件名爲factor.in。

共一行,包含5 個整數,分別爲 a ,b ,k ,n ,m,每兩個整數之間用一個空格隔開。

輸出格式:

輸出共1 行,包含一個整數,表示所求的係數,這個係數可能很大,輸出對10007 取模後的結果。

輸入樣例:

1 1 3 1 2

輸出樣例:

3

題解

首先根據二項式定理,我們可以得到(a+b)n=r=0nCnranrbr ,因爲題目中要求說是求(by+ax)k 展開後xnym 的係數,
我們設A=ax,B=by .則(ax+by)k=(A+B)k ,
套入二項式定理就可以得到
(A+B)k=r=0nCnrAnrBr ,
A=ax,B=by 代入就可以得到
(ax+by)k=r=0nCnr(ax)nr(by)r=r=0nCnranrbrxnryr
先求出組合數,然後用快速冪就可以求出係數了。

代碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#define ll long long
const int MAXN=1002;
ll c[MAXN][MAXN];
int n,m,a,b,k;
using namespace std;
void Init()
{
    c[0][0]=1;
    for(int i=1;i<=k;i++)
    {
        c[i][0]=1;
        for(int j=1;j<=k;j++)
        {
            c[i][j]=(c[i-1][j]%10007+c[i-1][j-1]%10007)%10007;
        }
    }
}
ll qsm(ll a,ll b)
{
    ll sum=1;
    while(b) 
    {
        if(b&1) 
        sum=(sum*a)%10007;
        a=a*a%10007;
        b>>=1;
    }
    return sum%10007;
} 
int main()
{
    scanf("%d%d%d%d%d",&a,&b,&k,&n,&m);
    Init();
    printf("%lld",(c[k][m]*(qsm(a,n)%10007*qsm(b,m)%10007))%10007);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章