给定一个多项式 (ax + by)k 。
输入a,b,k,n,m。
请求出多项式展开后 xnym 项的系数。
【数据范围】
对于 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。
分析:
根据二项式定理可知:xnym的系数是C(k,n)*an*bm。
关键是求C(k,n)的值:
方法一:
本题中k(<=1000)的值比较小,可以利用递推式C(k,n)=C(k-1,n-1)+C(k-1,n)直接求得。

1 const 2 maxn=1000; 3 md=10007; 4 var 5 f:array[0..maxn,0..maxn] of longint; 6 a,b,n,k,m,s,i,j:longint; 7 begin 8 assign(input,'factor.in'); reset(input); 9 assign(output,'factor.out'); rewrite(output); 10 readln(a,b,k,n,m); 11 a:=a mod md; 12 b:=b mod md; 13 f[0,0]:=1; 14 for i:=1 to k do begin f[i,0]:=1; f[i,i]:=1; end; 15 for i:=2 to k do 16 for j:=1 to i-1 do f[i,j]:=(f[i-1,j]+f[i-1,j-1])mod md; 17 s:=1; 18 for i:=1 to n do s:=(s*a)mod md; 19 for i:=1 to m do s:=(s*b)mod md; 20 writeln((f[k,n]*s)mod md); 21 end.
方法二:
如果k的范围再大的话,如k<=50000,就无法直接使用方法一中的递推式。
另一种解决问题的方法是:根据组合公式C(k,n)=(k*(k-1)*...*(k-n+1))/(1*2*...*n)
分子和分母分解质因数后约分即可(当然要先求出k以内的素数)。

1 const 2 maxk=100000; 3 md=10007; 4 fin='factor.in'; 5 fout='factor.out'; 6 var 7 p,e:array[1.. maxk] of longint; 8 f:array[1..maxk] of boolean; 9 a,b,k,n,m,cnt,s:longint; 10 procedure init; 11 begin 12 assign(input,fin); reset(input); 13 readln(a,b,k,n,m); 14 a:=a mod md; 15 b:=b mod md; 16 close(input); 17 end; 18 procedure make_p;//生成素数表 19 var i,j:longint; 20 begin 21 fillchar(f,sizeof(f),true); 22 cnt:=0; 23 for i:=2 to k do 24 if f[i] then 25 for j:=2 to k div i do f[i*j]:=false; 26 for i:=2 to k do 27 if f[i] then 28 begin inc(cnt); p[cnt]:=i; end; 29 end; 30 procedure make_e; //生成指数 31 var i,j,now:longint; 32 begin 33 fillchar(e,sizeof(e),0); 34 for i:=k-n+1 to k do //处理分子指数 35 begin 36 j:=i; now:=1; 37 while j>1 do 38 begin 39 while j mod p[now]=0 do 40 begin inc(e[now]); j:=j div p[now]; end; 41 inc(now); 42 end; 43 end; 44 for i:=1 to n do //处理分母指数 45 begin 46 j:=i; now:=1; 47 while j>1 do 48 begin 49 while j mod p[now]=0 do 50 begin dec(e[now]); j:=j div p[now]; end; 51 inc(now); 52 end; 53 end; 54 end; 55 procedure calc; 56 var i,j:longint; 57 begin 58 s:=1; 59 for i:=1 to cnt do 60 if e[i]>0 then 61 for j:=1 to e[i] do s:=(s*p[i])mod md; 62 for i:=1 to n do s:=(s*a)mod md; 63 for i:=1 to m do s:=(s*b)mod md; 64 end; 65 procedure print; 66 begin 67 assign(output,fout); rewrite(output); 68 writeln(s); 69 close(output); 70 end; 71 begin 72 init; 73 make_p; 74 make_e; 75 calc; 76 print; 77 end.