首页 > 其他分享 >转置原理与多项式多点求值

转置原理与多项式多点求值

时间:2023-12-06 17:12:44浏览次数:28  
标签:转置 多项式 pmatrix 多点 求值 vdots

终于学转置原理了,之前一直听 zhy 糊多项式题不知道他在讲写啥。

自己的多项式水平长期停留在多项式除法,直到今天做互测时被迫学了怎么去多点求值。正式比赛大概率不考(吧?)所以学来娱乐一下。

普通多点求值算法

思想很妙,效率很逊。代码不写了因为我连多项式取模都忘了怎么写了

考虑类似 CRT 和拉插的思想,对于点值集合 \(P\) 构造多项式 \(M_P(x)=\prod_{c\in P}(x-c)\)。这样就有了 \(\forall x\in P,M_P(x)=0\)。

然后考虑分治计算贡献,每次将点值均匀分成两个集合 \(P_0,P_1\),对于当前多项式 \(F\),多项式取模一下将其表示为 \(F=Q_0 M_{P_0}+F_0\) 和 \(F=Q_1 M_{P_1}+F_1\)。

那么你代入 \(P_0\) 中的点值时商的贡献就被消掉了,有 \(F(x)=F_0(x)\),这样 \(P,F\) 的规模双双减半。于是你往下递归做就可以了。\(M_P\) 可以在分治过程中递归维护出来。

每一层都带多项式取模(求逆)的 \(\log\),总复杂度 \(O(n\log^2 n)\),而且常数上天。

快速插值算法

多点求值本质上让我们乘上任意一个范德蒙德矩阵,而多项式操作基本上都是对于程序中变量的线性变换。这启发我们插值作为求值的逆算法也可以做到同等复杂度。

快速插值我们考虑对着拉插公式大力优化:\(F=\sum y_i \prod_{i\neq j} \frac{x-x_j}{x_i-x_j}\)。

考虑那个分母,这个东西里面似乎就是一个 \(M_{P/\{x_i\}}(x_i)\),也就是 \(M_P(x_i)\) 除以一个 \(x_i-x_i\),发现关键在零除零,那你发动技能“洛神”对里面大力洛必达一下,就可以得到 \(M_{P/\{x_i\}}(x_i)=M_P'(x_i)\)。也就是说你直接分治 NTT 出 \(M_P\) 之后求个导,然后再套多点求值就可以了!

剩下的相当于要计算 \(\sum \frac{y_i}{M_{P/\{x_i\}}(x_i)} \prod_{i\neq j} (x-x_j)\),直接上经典的缺一分治,也是分治 NTT,做完了!复杂度同多点求值,常数更上一层楼!

接下来是发病时间:

啊你看这个转置原理啊,就是说多点求值作为一个线性算法时可以分解成初等行矩阵然后去转置它(\((AB)^T=B^TA^T\))。那你也可以分解成初等行矩阵之后求逆它啊(\((AB)^{-1}=B^{-1}A^{-1}\))。

那你可以把多点求值中的所有变量都当成向量中的变量,把算法全部描述成乘上初等行变换矩阵,然后 reverse 一下这个操作序列,再一个一个还原回去就行了。

不要提常数的事,这个做法时空都是 \(O(n\log^2 n)\) 的毫无实际意义。

转置原理

看的王总博客

上面的技术在 EI 一行人引入转置原理之后就显得过时了整个多项式内容都过时了

多项式操作经常是线性变换,你仔细读一下 DFT 的代码就会发现你唯一做了的事要么就是将一个数的若干倍加到另一个数上,或者说交换两个数。

对于这种“线性算法”,它总能够被描述成乘上一个矩阵的样子 \(\vec{u}=A\vec{v}\),而且我们知道了如果它是可以快速做的,那么在同等的时间复杂度内它的逆变换时可以快速做的,具体看上文“发病时间“。同理它的转置算法,也就是求 \(A^T \vec{v}\) 也是可以快速做的。

卷积算法是可以转置的,这可以看王总博客。那 DFT 呢?搞笑了,它的转置就是它自己。

直接讲讲多点求值吧。多点求值就是直接乘上任意一种范德蒙德矩阵,相当于:

\[\begin{bmatrix} 1 & x_1 & x_1^2 & \cdots & x_1^n\\ 1 & x_2 & x_2^2 & \cdots & x_2^n\\ 1 & x_3 & x_3^2 & \cdots & x_3^n\\ \vdots & \vdots & \vdots & \ddots & \vdots\\ 1 & x_m & x_m^2 & \cdots & x_m^n \end{bmatrix} \begin{pmatrix} f_0\\ f_1\\ f_2\\ \vdots\\ f_n \end{pmatrix} = \begin{pmatrix} g_1\\ g_2\\ g_3\\ \vdots\\ g_m \end{pmatrix} \]

你把它转置,猜猜它是啥:

\[\begin{bmatrix} 1 & 1 & 1 & \cdots & 1\\ x_1 & x_2 & x_3 & \cdots & x_m\\ x_1^2 & x_2^2 & x_3^2 & \cdots & x_m^2\\ \vdots & \vdots & \vdots & \ddots & \vdots\\ x_1^n & x_2^n & x_3^n & \cdots & x_m^n \end{bmatrix} \begin{pmatrix} g_1\\ g_2\\ g_3\\ \vdots\\ g_m \end{pmatrix} = \begin{pmatrix} f_0\\ f_1\\ f_2\\ \vdots\\ f_n \end{pmatrix} \]

是你,带权等幂和问题!我们考虑先如何解决这个问题,写出 GF:

\[F(t)=\sum_{i=0}^m \frac{g_i}{1-x_it} \]

这里有个求和,看起来比较棘手。我们不妨考虑通分,用分治 NTT 去处理:

\[\frac{A_0}{B_0}+\frac{A_1}{B_1}=\frac{A_0B_1+A_1B_0}{B_0B_1} \]

用分治 NTT 直接维护出 \(A,B\) 就可以做了。

把这个算法转置一下,成啥样了呢?

注意一下所谓转置一定不要把不是输入输出的哪些东西转置了,也就是说常量运算不要转置。这个“常量”肯定不是一般讲的一个数,跟输入无关的多项式也要不转。比如说这个题中分母就是常量,你不要把预处理分母以及分母求逆的地方也转置了!

那么转置之后就变成了一个反着的分治,每次把多项式往底层递归而不是往上合并计算就可以了。注意这个过程中的多项式乘法是转置多项式乘法。

代码正在努力实现中。

标签:转置,多项式,pmatrix,多点,求值,vdots
From: https://www.cnblogs.com/yyyyxh/p/multipoint-eval-interpolation.html

相关文章

  • Day09 方法知识点综合(求值策略与可变参数)
    1.求值策略编程语言中方法之间进行参数传递时有个传递策略,该策略就被称为求值策略(Evaluationstrategies)。求值策略分为两大基本类型,如果按照如何处理传递给方法的实际参数,分为严格的和非严格的两种求值策略。1.1严格求值策略传值调用(Callbyvalue)将实参复制一份给形参......
  • AcWing 3302. 表达式求值
    题面:给定一个表达式,其中运算符仅包含加减乘除,可能包含括号,请你求出表达式的最终值。原题链接:3302.表达式求值-AcWing基本思路创建两个栈,分别存储数字和运算符运算符的判定:仅在以下条件满足时将运算符直接压入栈中:①栈中不存在元素②当前运算符优先级比栈顶高③栈顶为......
  • 欧氏空间上正规算子极小多项式的不可约分解诱导出全空间的正交直和分解
    ......
  • NX二次开发 转置矩阵 UF_MTX3_transpose
    简介:    NX二次开发转置矩阵UF_MTX3_transpose。代码:#include"me.hpp"externDllExportvoidufusr(char*param,int*returnCode,intrlen){UF_initialize();doubledMtx[9]={1.000000000,0.000000000,0.000000000,0.000000000......
  • 中缀表达式求值(栈的应用)
    一、题目来源AcWing算法基础课-3302.表达式求值二、题目描述给定一个表达式,其中运算符仅包含+,-,*,/(加减乘整除),可能包含括号,请你求出表达式的最终值。注意:数据保证给定的表达式合法。题目保证符号-只作为减号出现,不会作为负号出现,例如,-1+2,(2+2)*(-(1+1)+2)之类表......
  • 【未完善】多项式全家桶
    #include<iostream>#include<cmath>#include<cctype>#include<functional>#include<algorithm>#include<vector>#defineUP(i,s,e)for(autoi=s;i<e;++i)#defineDOWN(i,e,s)for(autoi=e;i-->s;)usingstd::c......
  • 7-2 栈实现表达式求值
    #include<iostream>#include<cstdio>#include<string>usingnamespacestd;constintN=100010;stringsplit(strings){    stringss;    for(inti=0;i<s.size();i++){        if(s[i]==32)continue;        ss+=char(s[i]);    }  ......
  • 算法学习笔记(41): 朴素多项式算法
    朴素多项式算法-\(O(n^2)\)合集我们并不需要NTT,就算需要,也只是用来优化乘法。多项式求逆对于多项式\(\suma_ix^i\)我们需要构造出一个多项式\(\sumb_ix^i\)使得:\[\begin{cases}a_0b_0=1\\\sum_{i=0}^ka_ib_{k-i}=0&k\ge1\end{cases}\]首先\(......
  • pp_orange的多项式模板
    /*Codebypp_orange*/#include<bits/stdc++.h>#definem_p(a,b)make_pair(a,b)#definepbpush_back#definelllonglong#defineullunsignedlonglong#definelldlongdouble#defineinf0x7FFFFFFF#defineinff9223372036854775807#definerep(i,l,......
  • MIT18.06Linear Algebra 第05讲 转置、置换和空间
    转载于:超详细MIT线性代数公开课笔记......