#zHSXybttg060601. 1648:【例 1】「NOIP2011」计算系数

1648:【例 1】「NOIP2011」计算系数

1648:【例 1】「NOIP2011」计算系数

题目描述

给定一个多项式 (ax+by)k(ax + by)^k,请求出多项式展开后 xnymx^n y^m 项的系数。

输入格式

输入共一行,包含 55 个整数,分别为 a,b,k,n,ma, b, k, n, m,每两个整数之间用一个空格隔开。

输出格式

输出共 11 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对 1000710007 取模后的结果。

样例

样例输入 #1

1 1 3 1 2

样例输出 #1

3

样例解释 #1

  • (ax+by)k=(x+y)3(ax + by)^k = (x + y)^3(因为 a=1,b=1a=1, b=1)。
  • 展开后 x1y2x^1 y^2 的系数:(x+y)3=x3+3x2y+3xy2+y3(x+y)^3 = x^3 + 3x^2 y + 3x y^2 + y^3,所以 xy2x y^2 的系数为 33
  • 输出 33

数据范围

  • 对于 30%30\% 的数据,有 k10k \le 10
  • 对于 50%50\% 的数据,有 a=1,b=1a = 1, b = 1
  • 对于 100%100\% 的数据,有 0n,mk0 \le n, m \le k,且 n+m=kn + m = k0a,b1060 \le a, b \le 10^6

时空限制

  • 时间限制:1000 ms
  • 内存限制:524288 KB

注意:根据二项式定理:

$$(ax + by)^k = \sum_{i=0}^{k} \binom{k}{i} (ax)^i (by)^{k-i} = \sum_{i=0}^{k} \binom{k}{i} a^i b^{k-i} x^i y^{k-i}$$

因此,xnymx^n y^m 项对应 i=ni = n,且 ki=mk - i = m,所以 n+m=kn + m = k(题目已保证)。该项的系数为:

(kn)anbm\binom{k}{n} a^n b^m

所以需要计算 (kn)×an×bmmod10007\binom{k}{n} \times a^n \times b^m \bmod 10007

由于 kk 可能很大(k=n+mk = n+mn,mn,m 可达 kk,但 kk 未给出上限,不过从数据范围看 kk 不会特别大?实际上题目未给出 kk 的上限,但 n,mkn,m \le kn+m=kn+m=k,所以 kk 可能达到 10310^3 或更高?但 a,b106a,b \le 10^6kk 可能也较大。但根据组合数计算,我们需要 (kn)\binom{k}{n}1000710007,可以用组合数公式 (kn)=k!n!(kn)!\binom{k}{n} = \frac{k!}{n! (k-n)!},但 kk 可能很大,不能直接计算阶乘。

由于模数 1000710007 是质数(检查:1000710007 是质数),我们可以使用费马小定理求逆元,配合预处理阶乘和逆元来计算组合数。但 kk 可能大于 1000710007,此时需要用到 Lucas 定理 计算组合数模质数。

Lucas 定理:对于质数 pp,有

$$\binom{n}{m} \bmod p = \binom{\lfloor n/p \rfloor}{\lfloor m/p \rfloor} \cdot \binom{n \bmod p}{m \bmod p} \bmod p$$

这样可以处理 n,mn, m 较大的情况。

因此,算法步骤:

  1. 读入 a,b,k,n,ma, b, k, n, m
  2. 计算 C=(kn)mod10007C = \binom{k}{n} \bmod 10007(使用 Lucas 定理)。
  3. 计算 anmod10007a^n \bmod 10007bmmod10007b^m \bmod 10007(快速幂)。
  4. 答案 ans=C×an×bmmod10007ans = C \times a^n \times b^m \bmod 10007

注意:a,ba, b 可能大于 1000710007,先取模。n,mn, m 可能大于 1000710007,但指数可以对 φ(10007)=10006\varphi(10007)=10006 取模?因为 1000710007 是质数,根据费马小定理,ap11(modp)a^{p-1} \equiv 1 \pmod{p},所以 anmodp=anmod(p1)modpa^n \bmod p = a^{n \bmod (p-1)} \bmod p(前提是 aa 不是 pp 的倍数)。但 aa 可能为 00,需要特判:如果 a0(mod10007)a \equiv 0 \pmod{10007}n>0n > 0,则 an0a^n \equiv 0;如果 n=0n=0,则 a0=1a^0 = 1。同样处理 bb

因此,计算 anmod10007a^n \bmod 10007 时,先让 amod=10007a \bmod= 10007,如果 a=0a=0n>0n>0,结果为 00;否则用快速幂计算 anmod10006mod10007a^{n \bmod 10006} \bmod 10007(因为 10006=10007110006 = 10007-1)。但注意:当 aa1000710007 互质时,费马小定理才成立;如果 aa1000710007 的倍数,则 a0(mod10007)a \equiv 0 \pmod{10007},直接得 00(除非 n=0n=0)。所以可以统一处理:先取模 aa,如果 a=0a=0n>0n>0,则 an=0a^n=0;否则用快速幂计算 anmod10007a^n \bmod 10007(指数 nn 不需要模 1000610006,因为 nn 可能很大,但快速幂可以处理大指数,取模即可)。

实际上,因为 1000710007 是质数,快速幂计算 anmod10007a^n \bmod 10007 时,指数 nn 不需要模 1000610006,因为快速幂每次乘取模,复杂度 O(logn)O(\log n)nn 可能很大(kk 可能很大),但 logn\log n 可以接受。但 kk 可能达到 10910^9?题目未给出上限,但 n,mkn,m \le k,且 a,b106a,b \le 10^6,但 kk 可能也很大。不过快速幂 O(logn)O(\log n) 可以处理 10910^9 的指数。

但 Lucas 定理需要计算 (kn)mod10007\binom{k}{n} \bmod 10007,其中 kk 可能很大,但 Lucas 定理将 kknn 表示为 pp 进制数,递归计算,复杂度 O(logpk)O(\log_p k)

实现 Lucas 定理需要预处理 00p1p-1 的阶乘和阶乘逆元。p=10007p=10007,可以预处理 fac[i]=i!modpfac[i] = i! \bmod pinv[i]=(i!)1modpinv[i] = (i!)^{-1} \bmod p,则 $\binom{n}{m} \bmod p = fac[n] \cdot inv[m] \cdot inv[n-m] \bmod p$(当 0mnp10 \le m \le n \le p-1)。

对于 k>pk > p 的情况,用 Lucas 定理递归。

注意:n,mn, m 满足 n+m=kn+m=k,所以 kn=mk-n=m

因此,完整算法:

  1. 预处理 fac[0..10006]fac[0..10006]inv[0..10006]inv[0..10006]
  2. 读入 a,b,k,n,ma, b, k, n, m
  3. 计算 C=lucas(k,n)C = lucas(k, n)
  4. 计算 A=powmod(a%MOD,n,MOD)A = pow_mod(a \% MOD, n, MOD)
  5. 计算 B=powmod(b%MOD,m,MOD)B = pow_mod(b \% MOD, m, MOD)
  6. 输出 C×A%MOD×B%MODC \times A \% MOD \times B \% MOD

其中 MOD=10007MOD = 10007

注意:aabb 可能为 00,且 nnmm00 时,000^0 在数学上未定义,但在本题中,当指数为 00 时,该项视为 11(因为 x0=1x^0 = 1)。所以需要特判:如果 n=0n=0,则 an=1a^n = 1;如果 n>0n>0a%MOD==0a \% MOD == 0,则 an%MOD=0a^n \% MOD = 0。类似处理 bb

另外,组合数 (kn)\binom{k}{n}n<0n<0n>kn>k 时为 00,但题目保证 0n,mk0 \le n,m \le kn+m=kn+m=k,所以 nn[0,k][0,k] 内。