多项式小结

多项式

一 简介

**多项式的度:**对于一个多项式 f ( x ) f(x) f(x),称其最高次项的次数为该多项式的度,记作 d e g   f deg\ f deg f

多项式的乘法:

可以通过快速傅里叶变换在 O ( n l o g n ) O(nlogn) O(nlogn)下计算。

给定多项式 f ( x ) f(x) f(x) g ( x ) g(x) g(x)
f ( x ) = a 0 + a 1 x + ⋅ ⋅ ⋅ + a n x n g ( x ) = b 0 + b 1 x + ⋅ ⋅ ⋅ + b m x m f(x)=a_0+a_1x+···+a_nx^n \\ g(x)=b_0+b_1x+···+b_mx^m f(x)=a0+a1x++anxng(x)=b0+b1x++bmxm
计算多项式 Q ( x ) = f ( x ) ⋅ g ( x ) Q(x)=f(x)·g(x) Q(x)=f(x)g(x)
Q ( x ) = ∑ i = 0 n ∑ j = 0 m a i b j x i + j = c 0 + c 1 x + ⋅ ⋅ ⋅ + c n + m x n + m Q(x)=\sum_{i=0}^{n}\sum_{j=0}^{m}a_ib_jx^{i+j}=c_0+c_1x+···+c_{n+m}x^{n+m} Q(x)=i=0nj=0maibjxi+j=c0+c1x++cn+mxn+m
多项式的逆元:

对于多项式 f ( x ) f(x) f(x),若存在 g ( x ) g(x) g(x)满足:
f ( x ) g ( x ) ≡ 1   ( m o d   x n ) d e g   g ≤ d e g   f f(x)g(x)≡1\ (mod\ x^n) \\ deg\ g≤deg\ f f(x)g(x)1 (mod xn)deg gdeg f
则称 g ( x ) g(x) g(x) f ( x ) f(x) f(x)在模 x n x^n xn意义下的逆元,记作 f − 1 ( x ) f^{-1}(x) f1(x)

多项式的余数和商:

对于多项式 f ( x ) , g ( x ) f(x),g(x) f(x),g(x),存在唯一的 Q ( x ) , R ( x ) Q(x),R(x) Q(x),R(x)满足:
f ( x ) = Q ( x ) g ( x ) + R ( x ) d e g   Q = d e g   f − d e g   g d e g   R < d e g   g f(x)=Q(x)g(x)+R(x) \\ deg\ Q=deg\ f-deg\ g \\ deg\ R<deg\ g f(x)=Q(x)g(x)+R(x)deg Q=deg fdeg gdeg R<deg g
Q ( x ) Q(x) Q(x) g ( x ) g(x) g(x) f ( x ) f(x) f(x)的商, R ( x ) R(x) R(x) g ( x ) g(x) g(x) f ( x ) f(x) f(x)的余数,可记作:
f ( x ) = R ( x )   ( m o d   g ( x ) ) f(x)=R(x)\ (mod\ g(x)) f(x)=R(x) (mod g(x))
多项式的对数函数与指数函数:

对于一个多项式 f ( x ) f(x) f(x),可以将其对数函数看作其与麦克劳林级数的复合:
l n ( 1 − f ( x ) ) = − ∑ i = 1 + ∞ f i ( x ) i l n ( 1 + f ( x ) ) = ∑ i = 1 + ∞ ( − 1 ) i − 1 f i ( x ) i ln(1-f(x))=-\sum_{i=1}^{+∞}\frac{f^i(x)}{i} \\ ln(1+f(x))=\sum_{i=1}^{+∞}\frac{(-1)^{i-1}f^i(x)}{i} ln(1f(x))=i=1+ifi(x)ln(1+f(x))=i=1+i(1)i1fi(x)
其指数函数可以定义:
e x p   f ( x ) = e f ( x ) = ∑ i = 0 + ∞ f i ( x ) i ! exp\ f(x)=e^{f(x)}=\sum_{i=0}^{+∞}\frac{f^i(x)}{i!} exp f(x)=ef(x)=i=0+i!fi(x)
多项式的多点求值和插值:

多项式的多点求值:给出一个多项式 f ( x ) f(x) f(x) n n n个点 x 1 , x 2 , . . . , x n x_1,x_2,...,x_n x1,x2,...,xn,求 f ( x 1 ) , f ( x 2 ) , . . . , f ( x n ) f(x_1),f(x_2),...,f(x_n) f(x1),f(x2),...,f(xn)

多项式的插值:给出 n + 1 n+1 n+1个点 ( x 0 , y 0 ) , ( x 1 , y 1 ) , . . . , ( x n , y n ) (x_0,y_0),(x_1,y_1),...,(x_n,y_n) (x0,y0),(x1,y1),...,(xn,yn),求一个 n n n次多项式 f ( x ) f(x) f(x)使得这 n + 1 n+1 n+1个点都在 f ( x ) f(x) f(x)上。

两种操作实质是将多项式在系数表示和点值表示间转化。

二 拉格朗日插值

2.1 知识点

时间复杂度: O ( n 2 ) O(n^2) O(n2)

**问题:**给出 n n n个点 P i ( x i , y i ) P_i(x_i,y_i) Pi(xi,yi),将过这 n n n个点的最多 n − 1 n-1 n1次的多项式记为 f ( x ) f(x) f(x),求 f ( k ) f(k) f(k)的值。

**差分法:**适用于 x i = i x_i=i xi=i的情况。

利用差分法求多项式 f ( x ) = ∑ i = 0 n a i x i f(x)=\sum_{i=0}^{n}a_ix^i f(x)=i=0naixi的多项式形式,时间复杂度 O ( n 2 ) O(n^2) O(n2)

已知 f ( 1 ) f(1) f(1) f ( 6 ) f(6) f(6)的值分别为 1 , 5 , 14 , 30 , 55 , 91 1,5,14,30,55,91 1,5,14,30,55,91
KaTeX parse error: Undefined control sequence: \ at position 140: …\ \ 2\ \ \ \ \ \̲ ̲
第一行为 f ( x ) f(x) f(x)的连续的前 n n n项,之后每一行为上一行相邻两项的差值,最终会变成定值行,即可求解。

待定系数法:

f ( x ) = ∑ i = 0 n − 1 a i x i f(x)=\sum_{i=0}^{n-1}a_ix^i f(x)=i=0n1aixi,将每个 x i x_i xi代入 f ( x ) f(x) f(x),得到一个由 n n n n n n元一次方程所组成的方程组,然后使用高斯消元求解

拉格朗日插值法:

有:
f ( x ) ≡ f ( a )   ( m o d   ( x − a ) ) f(x)≡f(a)\ (mod\ (x-a)) f(x)f(a) (mod (xa))
因为 f ( x ) − f ( a ) = ( a 0 − a 0 ) + a 1 ( x 1 − a 1 ) + a 2 ( x 2 − a 2 ) + ⋅ ⋅ ⋅ + a n ( x n − a n ) f(x)-f(a)=(a_0-a_0)+a_1(x^1-a^1)+a_2(x^2-a^2)+···+a_n(x^n-a^n) f(x)f(a)=(a0a0)+a1(x1a1)+a2(x2a2)++an(xnan)有因子 ( x − a ) (x-a) (xa)

列出多项式线性同余方程组:
$$

\begin{cases} f(x)≡y_1\ (mod\ (x-x_1)) \ f(x)≡y_2\ (mod\ (x-x_2)) \ ··· \ f(x)≡y_n\ (mod\ (x-x_n)) \end{cases}
根 据 中 国 剩 余 定 理 : 根据中国剩余定理:
M=\prod_{i=1}^{n}(x-x_i) \
m_i=\frac{M}{x-x_i}=\prod_{j≠i}(x-x_j)
KaTeX parse error: Can't use function '$' in math mode at position 2: $̲m_i$模$(x-x_i)$意…
m_i^{-1}=\prod_{j≠i}\frac{1}{x_i-x_j}
所 以 : 所以:
f(x)=\sum_{i=1}{n}y_im_im_i{-1}≡\sum_{i=1}^ny_i\prod_{j≠i}\frac{x-x_i}{x_i-x_j}\ (mod\ M)
$$

如果给定的点为连续的点,那么可以使用前缀后缀优化。

例如给定 ( 0 , f 0 ) , ( 1 , f 1 ) , ( 2 , f 2 ) , . . . , ( n , f n ) (0, f_0), (1, f_1), (2, f_2), ..., (n, f_n) (0,f0),(1,f1),(2,f2),...,(n,fn)

则记: p r e [ i ] = ∏ j = 0 i ( k − j ) , s u f f [ i ] = ∏ j = i n ( k − j ) , f a c t [ i ] = i ! pre[i] = \prod_{j=0}^{i}(k - j), suff[i] = \prod_{j=i}^{n}(k-j), fact[i] = i! pre[i]=j=0i(kj),suff[i]=j=in(kj),fact[i]=i!

则$ f(k)=\sum_{i=0}^{n} y_i\frac{pre[i-1]*suff[i+1]}{fact[i]*fact[n-i]} , 但 是 分 母 , 但是分母 ,fact[n-i]$可能出现负数,需要去判断,当 n − i n-i ni 为奇数时,分母应该取负号。这样就可以预处理得到 f a c t fact fact数组,然后根据输入的k来 O ( n ) O(n) O(n)计算得到 p r e 、 s u f f pre、suff presuff数组,从而 O ( n ) O(n) O(n)完成 f ( k ) f(k) f(k)计算。

2.2 模板

2.1 随机给定n个点插值: O ( n 2 l o g n ) O(n^2log_n) O(n2logn)

#include <bits/stdc++.h>

#define int long long
using namespace std;

const int MAXN = 2010;
int mod = 998244353;
int n, k, x[MAXN], y[MAXN], res, s1, s2;

int qmi(int a, int k, int p) {
   
    int res = 1 % p;  // res记录答案, 模上p是为了防止k为0,p为1的特殊情况
    while(k) {
     // 只要还有剩下位数
        if (k & 1) res = res * a % p;  // 判断最后一位是否为1,如果为1就乘上a,模上p, 乘法时可能爆int,所以变成long long
        k >>= 1;  // 右移一位
        a = a * a % p;  // 当前a等于上一次的a平方,取模,平方时可能爆int,所以变成long long
    }
    return res;
}

int get_inv(int a, int p) {
   
    return a % p == 0? -1: qmi(a, p - 2, p);
}

// n个点(x[i], y[i]),求f(k)
int Lagrange(int x[], int y[], int n, int k) {
   
    int res = 0;
    for (int i = 1; i <= n; i++) {
   
        s1 = y[i] % mod;  // s1计算分子
        s2 = 1;  // s2计算分母
        for (int j = 1; j <= n; j++)
            if (i != j)
                s1 = s1 * (k - x[j]) % mod, s2 = s2 * (x[i] - x[j]) % mod;  // 分别计算分子和分母
        res += s1 * get_inv(s2, mod) % mod;
    }
    return (res % mod + mod) % mod;
}

signed main() {
   
    scanf("%lld%lld", &n, &k);
    for (int i = 1; i <= n; i++) scanf("%lld%lld", x + i, y + i);  // 读入n个点
    cout << Lagrange(x, y, n, k);
    return 0;
}

2.2 给定连续n个点插值: O ( n ) O(n) O(n)

void init(int n, int mod) {
     // 预处理逆元
    LL res = 1;
    for (int i = 1; i <= n + 2; ++i) res = res * i % mod;  // 计算阶乘
    fact[n + 2] = qmi(res, mod - 2, mod);  
    for (int i = n + 1; i >= 0; --i) fact[i] = (i + 1) * fact[i + 1] % mod;  // 计算逆元
}

//给定最高次为n的多项式的n+1个点分别为:(0,f0),(1,f1),(2,f2)...(n,fn),求f(k)的值
LL Lagrange(LL f[], int n, int k) {
   
    if (k <= n) return f[k];
    pre[0] = suff[n + 1] = 1;
    for (int i = 0; i <= n; ++i) pre[i + 1] = pre[i] * (k - i) % mod;
    for (int i = n; i >= 0; --i) suff[i] = suff[i + 1] * (k - i) % mod;
    LL fk = 0;
    for (int i = 0; i <= n; ++i) {
   
        LL tmp = f[i] * pre[i] % mod * suff[i + 1] % mod * fact[i] % mod * fact[n - i] % mod;  // 计算 (pre[i-1]*suff[i+1]) / (fact[i]*fact[n-i])
        if ((n - i) & 1)  // 当 n-i 为奇数时,分母应该取负号。
            fk = (fk - tmp + mod) % mod;
        else
            fk = (fk + tmp) % mod;
    }
    return fk;
}

int main() {
   
    ...
    init(MAXN - 10, mod);  // 预处理逆元
    for (int i = 0; i <= n; ++i) cin >> f[i];  // 读入n+1个点
    f[n + 1] = Lagrange(f, n, n + 1);  // 得到f[n+1]
    ...
}

2.3 例题

P4781 【模板】拉格朗日插值

**题意:**给定 n n n个点 ( x i , y i ) (x_i,y_i) (xi,yi)确定唯一的多项式,并求出 f ( k )   m o d   998244353 f(k)\ mod\ 998244353 f(k) mod 998244353

数据: 1 ≤ n ≤ 2 × 1 0 3 1≤n≤2×10^3 1n2×103 1 ≤ x i , y i , k < 998244353 1≤x_i,y_i,k<998244353 1xi,yi,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值