描述
给定一个多项式(ax + by)^k,请求出多项式展开后x^n * y^m项的系数。
格式
输入格式
共一行,包含5个整数,分别为a,b,k,n,m,每两个整数之间用一个空格隔开。
输出格式
输出共1行,包含一个整数,表示所求的系数,这个系数可能很大,输出对10007取模后的结果。
限制
1s
提示
对于30%的数据,有0 ≤ k ≤ 10;
对于50%的数据,有a = 1, b = 1;
对于100%的数据,有0 ≤ k ≤ 1000,0 ≤ n, m ≤ k,且n+m = k,0 ≤ a,b ≤ 1,000,000.
分析:求系数的题目,二项式定理,杨辉三角都可以,还可以用更高级的单位根法(高数内容,高中应该预习一下)
解一:二项式定理+组合公式
C(m,n+1)=C(m,n)+C(m-1,n)
此公式证明如下:
现在我们有n+1个球,我们从里面选m个。 这个我们知道共有C(m,n+1)种选法。 然后我们在这n+1个球里随便挑一个,叫它a球。 那么在这C(m,n+1)种选法里就分成了两类,且只有这两类。 一类是选出来的m个球里没有a球。 这类选法数量等价于n个球里选m个,就是C(m,n) 还有一类是选出来的m个球里有a球。 这类选法数量等价于n个球里选m-1个,就是C(m-1,n)
const mo=10007;
var
a,b,k,n,m,i,j:longint;
f:array[0..1000,0..1000]of int64;
begin
read(a,b,k,n,m);
fillchar(f,sizeof(f),0);
f[0,0]:=1;
for i:=1 to n do f[i,0]:=f[i-1,0];
for i:=1 to m do f[0,i]:=f[0,i-1];
for i:=1 to n do
for j:=1 to m do
f[i,j]:=(f[i-1,j] mod mo+f[i,j-1] mod mo)mod mo;//计算组合数
for i:=1 to n do
f[n,m]:=(f[n,m]*a) mod mo;//计算系数
for i:=1 to m do
f[n,m]:=(f[n,m]*b) mod mo;
writeln(f[n,m] mod mo);
end.
解二:
快速幂+杨辉三角
var a,b,n,m,k,i:longint;
tmp1,tmp2,tmp3,ans:int64;
function fast(x,n:longint):int64;
var y:int64;
begin
fast:=1;
y:=x;
while n>0 do
begin
if odd(n) then fast:=fast*y mod p;
y:=y*y mod p;
n:=n shr 1;
end;
end;
begin
assign(input,'factor.in'); reset(input);
assign(output,'factor.out'); rewrite(output);
readln(a,b,k,n,m);
tmp1:=fast(a,n);
tmp2:=fast(b,m);
tmp3:=1;
for i:=1 to n do
tmp3:=tmp3*(k-i+1)*fast(i,p-2) mod p;
ans:=tmp1*tmp2*tmp3 mod p;
writeln(ans);
close(input);
close(output);
end.
解三:纯用杨辉三角
用杨辉三角,ans=a^n*b^m*f[k,m+1]。一边计算一边摸,否则会爆。用int64.
var f:array[0..1005,0..1005]of int64;
a,b,k,n,m,i,j:longint;
x,y,ans:int64;
begin
//assign(input,'factor.in');
reset(input);
//assign(output,'factor.out');rewrite(output);
readln(a,b,k,n,m);
f[1,1]:=1;
for i:=2 to k+1 do
for j:=1 to i do
f[i,j]:=(f[i-1,j-1]+f[i-1,j])mod 10007;
x:=1;
y:=1;
for i:=1 to n do x:=x*a mod 10007;
for i:=1 to m do y:=y*b mod 10007;
ans:=x*y*f[k+1,m+1] mod 10007;
writeln(ans);
//close(input);close(output);
end.