给定一个多项式(by+ax)^k,请求出多项式展开后x^n*y^m 项的系数。
输入输出格式
输入格式:
输入文件名为factor.in。
共一行,包含5 个整数,分别为 a ,b ,k ,n ,m,每两个整数之间用一个空格隔开。
输出格式:
输出共1 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对10007 取模后的结果。
输入输出样例
输入样例#1:
1 1 3 1 2
输出样例#1:
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。
noip2011提高组day2第1题
神奇的数学题,直接提示了二项式定理( 其实就是说杨辉三角与二项式的系数相同,与C(n,m)相同 )
由定理直接可以得出第x^n*y^m 项为:C(k,m)* (a*x)^n* (b*y)^m
化简可得其系数为: C(k,m) * a^n * b^m
PS:由于二项式/杨辉三角性质可知 n+m=k 则 C(k,m)=C(k,k-n)=C(k,n)
对于后二者,直接用快速幂(如果不知道,那么88,走错片场了)来求就行了.
对于C(k,m),有两种方法,其一是形如杨辉三角的递推(C(k,m)=C(k-1,m-1)+C(k-1,m)).其二是考虑分解质因数+高精度或逆元(因为要取模) ( C(k,m)=k!/( (m-k)!*m! ) )
对此仅给出逆元的解法(快速幂求逆元)
1.逆元定义:对于正整数a和m,如果有 a*x≡1(mod m) { 即 a*x%m=1%m },那么把这个同余方程中的最小正整数解叫做a模m的逆元。
2.费马小定理:假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p),即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1
3.对于除法取模来说 (a/b)%m=((a%mo)/(b%mo))%mo 是不存在的但对于+ - * ^ 来说成立,所以说可以考虑将 (a/b)%m转化为 a*(b^-1)%mo . 当然,直接转换是不存在的,于是借助逆元进行转化
由于mo=10007为质数,与b=(m-k)!* m! 互质,所以,由费马小定理可得: b^(mo-1)=1(mod mo) 又因为 b^-1*b=1
so b^(mo-1)=b^-1*b –> b^-1=b^(mo-2)
于是 (令 b=(m-k)!* m!)
C(k,m)%mo=( k!/b) %mo=( k! b^-1 )%mo=( k! *b^(mo-2))%mo=((k!%mo) ( (b%mo)^(mo-2)%mo))%mo
其中b^(mo-2)可用快速幂解决
数论代码一般都十分丑陋
貌似不用开long long的样子
#include
#include
#define open(s) freopen(s".in","r",stdin); freopen(s".out","w",stdout);
#define close fclose(stdin); fclose(stdout);
using namespace std;
int mo=10007;
int jc[1005];
inline int read()
{
int k=1;
int sum=0;
char c=getchar();
for(;'0'>c || c>'9' ;c=getchar())
if(c=='-') k=-1;
for(;'0'<=c && c<='9';c=getchar())
sum=sum*10+c-'0';
return sum*k;
}
inline void write(int x)
{
if(x<0) { putchar('-'); x*=-1; }
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline int power(int x,int t)//快速幂 x^t
{
if(t==1) return x;
int s=power(x,t>>1);
s=s*s%mo;
return t&1?s*x%mo:s;
}
int main()
{
open("1313");
int a=read(),b=read(),k=read(),n=read(),m=read();
jc[0]=1;
for(int i=1;i<=k;++i) jc[i]=(jc[i-1]*i)%mo;//预处理阶乘
n%=mo; m%=mo;//由于n,m,a,b都可能比mo大,所以先取模
a%=mo; b%=mo;
int ans=1;
//三部分
ans=(jc[k]*power((jc[k-n]*jc[n])%mo,mo-2))%mo;
ans=(ans*power(a,n))%mo;
ans=(ans*power(b,m))%mo;
write(ans);
close;
return 0;
}