计算系数

先导

根据高中的数学知识二项式定理,我们可以得到

((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;
}
原文地址:https://www.cnblogs.com/bangdexuanyuan/p/14396904.html