题意
3601 计算系数 0x30「数学知识」例题
描述
给定一个多项式(ax+by)^k,请求出多项式展开后x^n*y^m项的系数。
输入格式
共一行,包含5 个整数,分别为 a ,b ,k ,n ,m,每两个整数之间用一个空格隔开。
输出格式
输出共1 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对10007 取模后的结果。
样例输入
1 1 3 1 2
样例输出
3
数据范围与约定
- 对于30% 的数据,有 0 ≤k ≤10 ;
对于50% 的数据,有 a = 1,b = 1;
对于100%的数据,有 0 ≤k ≤1,000,0≤n, m ≤k ,且n + m = k ,0 ≤a ,b ≤1,000,000。
来源
CCF NOIP2011 D2T1
分析
根据二项式定理展开式子
\[ (ax+by)^k=\sum_{i=0}^k \binom{k}{i}a^ix^ib^{k-i}y^{k-i} \]
所以\(x^ny^m\)的系数是\(\binom{k}{n}a^n b^m\),预处理逆元即可。
时间复杂度\(O(n \log n)\)
代码
#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;
rg char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') w=-1;
ch=getchar();
}
while(isdigit(ch))
data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x){
return x=read<T>();
}
typedef long long ll;
co int P=10007;
int x,y,inv[1001];
int exgcd(int a,int b){
if(!b) {x=1,y=0;return a;}
int d=exgcd(b,a%b);
int z=x;x=y,y=z-y*(a/b);
return d;
}
int main()
{
// freopen(".in","r",stdin),freopen(".out","w",stdout);
for(int i=1;i<=1000;++i)
exgcd(i,P),inv[i]=x;
int a,b,k,n,m;
read(a),read(b),read(k),read(n),read(m);
int ans=1;
a%=P,b%=P;
n=std::min(m,n);
for(int i=1;i<=n;++i)
ans=ans*inv[i]%P*(k+1-i)%P;
for(int i=1;i<=n;++i) ans=ans*a%P;
for(int i=1;i<=m;++i) ans=ans*b%P;
printf("%d\n",(ans%P+P)%P);
return 0;
}