闲话 24.10.13
闲话
还有不到两周就 csp-j/s 了(
祝大家别挂分(
没有闲话题材了啊!
今日推歌:花朵 by 合目 feat. 诗岸
那些你不要的:拉格朗日……插值?
给定 \(n, k\)。给定一个 \(n\) 阶多项式 \(f(x)\),以及 \(k\) 个无重根首一多项式 \(f_1(x), \dots, f_k(x)\),第 \(i\) 个多项式的次数为 \(m_i > 0\)。\(f(x)\) 给定系数,\(f_i(x)\) 给定 \(m_i\) 个根。对每个 \(i\) 求算 \(f(x) \bmod f_i(x)\)。
\(1\le \sum_i m_i, n\le 10^5\)。
一个高等代数的做法是这样的:令 \(r_i(x) = f(x) \bmod f_i(x)\),那么其为满足 \(f(x) = q(x) f_i(x) + r(x)\) 的 \(r(x)\) 中最短者。而带入 \(f_i(x) = \prod_{j = 1}^{m_i} (x - x_j)\) 的 \(m_i\) 个根知道 \(r(x_j) = f(x_j)\)。则显然通过拉格朗日插值能确定这个最短多项式 \(r_i(x)\)。
那么对一般的情况,只需要对 \(f(x)\) 和这 \(\sum m_i\) 个根运行多点求值,再分别运行快速插值即可。总时间复杂度 \(O(n\log^2 n)\),常数*可能*不是很大。
另一个由古典多点求值算法导出的做法是这样的:注意到对 \(f(x), m_1(x), m_2(x)\),\(f(x)\bmod m_1(x) = \left(f(x) \bmod m_1(x)m_2(x)\right) \bmod m_1(x)\),那么先求出 \(f_i(x)\) 的多项式形式,把它们排成一排,按照度数之和每次从近似中点先合并,再分治取模即可。总时间复杂度也是 \(O(n\log^2 n)\),常数听说不小。
所以说上面那个做法其实没啥实际作用,而且限制挺大的,比如 \(f_i(x)\) 都要无重根。当然如果 \(f(x)\) 和需要的信息够特殊,比如能 \(O(n)\) 对 \(f(x)\) 做多点求值,并且不需要求最短多项式的系数而是远点求值,那总复杂度就可以优化到 \(O(n)\) 了。
根据 jjdw 的阐述,我们可以不直接用拉格朗日插值,而且甚至可以不需要无重根的性质。那么我们接下来不使用无重根性质,即 \(f_i(x) = \prod_{j = 1}^{m_i} (x - x_j)^{c_j}\)。如果我们能求算每个 \(f(x) \bmod (x - x_j)^{c_j}\),那么根据多项式 CRT,存在一种方法计算 \(f(x) \bmod \prod_{j = 1}^{m_i} (x - x_j)^{c_j}\)。那么这种方法是什么呢?
回忆一下多项式 CRT 的构造:取 \(f_i(x) = \prod_{j = 1}^{m_i} (x - x_j)^{c_j}, p_j(x) = (x - x_j)^{c_j}\),以及 \(f_i(x) / p_j(x)\) 在 \(\bmod p_j(x)\) 意义下的逆元 \(v_j(x) = \left[f_i(x) / p_j(x) \bmod p_j(x)\right]^{-1}\bmod p_j(x)\)。那么 \(r_i(x) = \sum_{j = 1}^{m_i} f(x_j) f_i(x) / (x - x_j) v_j(x)\)。那么要对每个 \(1\le j \le m_i\) 求算 \(v_j(x)\)。首先考虑求算 \(P_j(x) = f_i(x) / p_j(x) \bmod p_j(x)\),这个直接通过分治树即可得到。接下来考虑求逆。考虑代换 \(t = x - x_j\),容易发现这变换是保度数的,因此我们只需要先求 \(P_j(t + x_j)\) 在模 \(t^{c_j}\) 意义下的逆,然后代换回去即可。
上面的内容摘自 分式分解,给小朋友们做现场的表演。
这个还是 \(O(n\log^2 n)\) 的,分治树那一部分的常数感觉和上面第二个做法没啥区别啊。
然而最重要的一点就是:给定根这个性质太少见了。所以到目前为止这个东西还停留在理性愉悦阶段。
以下是博客签名,与正文无关。
请按如下方式引用此页:
本文作者 joke3579,原文链接:https://www.cnblogs.com/joke3579/p/-/chitchat241013。
遵循 CC BY-NC-SA 4.0 协议。
请读者尽量不要在评论区发布与博客内文完全无关的评论,视情况可能删除。