先导
根据高中的数学知识二项式定理,我们可以得到
((x+y)^n=C_{n}^0x^ny^0+C_{n-1}^1x^{n-1}y1+...+C_{n}^nx^0y^n)
我们可以这样理解,比如这样一个式子,((x+y)^5)
如果我们要求(x^3y^2)的系数,那么我们想象成有(()()()()())个括号连续相乘,为了得到(x^3y^2)
我们需要从(5)个括号中选出(3)个来作为(x)相乘的项,即(C_{5}^3)((x)^3)
另外还剩下两个括号,我们选出(2)个括号作为(y)相乘的项,即(C_{2}^2(y)^2)
最后把这两个分散的项相乘得到(C_{5}^3(x)^3C_{2}^2(y)^2)
推广
那么进行推广我们可以得到
((x+y+z)^n)如果要求(x^ay^bz^c)的系数
还是想象成有(n)个括号连续相乘
从(n)个括号中选出(a)个凑成(x^a),即(C_{n}^a(x)^a)。
从剩下的(n-a)个括号选出(b)个凑出(y^b),即(C_{n-a}^b(y)^b)。
最后从剩下的(n-a-b)个括号中选出(c)个凑出(z^c),即(C_{n-a-b}^c(z)^c)
最后的最后把这些分散的项相乘就是最终(x^ay^bz^c)的系数
(注意,我这里之所以要把(x,y,z)外面带上括号,就是因为某些情况下,(x)前面的系数可能不为1,这个时候还要把(x)前面的系数也算上)
比如要求(x^3y^2)
((2x+3y)^5=C_{5}^3(2x)^3C_{2}^2(3y)^2)
有了上面的知识储备,下面的这道题一定就非常简单了
真题
给定一个多项式((ax+by)^k),请求出多项式展开后(x^ny^m)项的系数。
输入格式
共一行,包含 5 个整数,分别为 (a,b,k,n,m),每两个整数之间用一个空格隔开。
输出格式
输出共 1 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对10007 取模后的结果。
数据范围
(0≤n,m≤k≤1000)
(n+m=k)
(0≤a,b≤10^6)
输入样例:
1 1 3 1 2
输出样例:
3
题解
从连续的(k)个括号中选出(n)个作为凑成(x^n)
(C_{k}^n(ax)^n)
从剩下的(k-n)个括号中选出(m)个凑成(y^m)
(C_{k-n}^{m}(by)^m)
最后答案(C_{k}^n(ax)^n)(C_{k-n}^{m}(by)^m)
所以我们的代码只需要处理
(a^n),(b^m),还有组合数的计算就行
代码
#include <cmath>
#include <iostream>
using namespace std;
const int mod = 10007;
const int N = 1010;
int a, b, k, n, m;
int c[N][N];
void init() {
for (int i = 0; i <= 1000; i++)
for (int j = 0; j <= i; j++) {
if (j == 0)
c[i][j] = 1;
else
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
}
int qmi(int a, int b) {
int ans = 1;
while (b) {
if (b & 1) ans = (long long)ans * a % mod;
a = (long long)a * a % mod;
b >>= 1;
}
return ans % mod;
}
int main() {
init(); //预处理出组合数
cin >> a >> b >> k >> n >> m;
cout << (long long)qmi(a, n) * qmi(b, m) * c[k][n] % mod;
return 0;
}