多项式总结&多项式板子

三角/反三角是不可能放的(也不可能真香的


多项式乘法(DFT,FFT,NTT,MTT)

背板子

前置知识:泰勒展开

如果\(f(x)\)在\(x_0\)处存在\(n\)阶导,那么

\[f(x)=\sum_{i=0}^{\infty}\frac{f^i(x_0)}{i!}(x-x_0)^i
\]

称作\(f(x)\)在\(x_0\)处的泰勒展开。

前置知识:牛顿迭代

有一个\(n-1\)次多项式\(A(x)\),你需要求\(B(x)\)满足\(A(B(x))\equiv 0(\mod x^n)\)

如果\(n=1\)就只有常数项,直接计算就行了

否则令\(m=\lceil\frac n2\rceil\),递归地求\(B_m(x)\)。(\(B_m(x)=B(x)\mod x^m\))

然后根据\(B_m\)和\(A\)推出\(B_n\)。

\(A(B_n(x))\)在\(B_m(x)\)处泰勒展开,\(A(B_n(x))=A(B_m(x))+A'(B_m(x))(B_n(x)-B_m(x))\)

(然后后面的因为\((B_n(x)-B_m(x))\)是\(x^m\)的倍数,而结果要\(\mod x^n\)所以都没了)

左边为0,化简得到了\(B_n(x)=B_m(x)-\frac{A(B_m(x))}{A'(B_m(x))}\)

如果推的过程是\(O(n\log n)\),那么总复杂度是\(T(n)=T(n/2)+O(n\log n)=O(n\log n)\)很小但常数就不一定了

多项式求导/积分

只需要知道\((x^n)'=nx^{n-1}\),\(\int(x^n)=\frac{1}{n+1}x^{n+1}\)就行了

多项式求逆

有一个\(n-1\)次多项式\(A(x)\),你要求\(B(x)\)满足\(A(x)B(x)\equiv 1(\mod x^n)\)

用牛顿迭代做。

\(A(x)B(x)=1\),设\(F(B(x))=A(x)B(x)-1\),那么要求\(F(B(x))=0\)。

带入上面的式子,\(B_n(x)=B_m-\frac{AB_m-1}{A}\)

注意\(B\)是\(A\)的逆,所以化简\(B_n(x)=2B_m(x)-AB_m^2(x)\)

多项式开根

有一个\(n-1\)次多项式\(A(x)\),你要求\(B(x)\)满足\(B(x)^2\equiv A(x)(\mod x^n)\)

同上,构造\(F(B(x))=B(x)^2-A(x)=0\)。

代入,\(B_n(x)=B_m(x)-\frac{B_m(x)^2-A(x)}{2B_m(x)}\)

化简,\(B_n(x)=\frac 12(B_m(x)+\frac{A(x)}{B_m(x)})\)

多项式\(\ln\)

不用牛顿迭代

有一个\(n-1\)次多项式\(A(x)\),你要求\(B(x)\)满足\(B(x)=\ln A(x)(\mod x^n)\)

注意多项式函数必须要满足常数项在膜意义下可以做,比如\(\ln\)保证常数项为\(1\)

\(B(x)=\ln A(x)\)

\(B'(x)=(\ln A(x))'=\frac{A'(x)}{A(x)}\)

\(B(x)=\int \frac{A'(x)}{A(x)}\)

多项式\(\exp\)

这个常数略大,可能被分治\(NTT\)吊打。

有一个\(n-1\)次多项式\(A(x)\),你要求\(B(x)\)满足\(A(x)=\ln B(x)(\mod x^n)\)

牛顿迭代,\(F(B(x))=\ln B(x)-A(x)=0\)

化简,\(B_n(x)=B_m(x)(1-\ln(B_m(x))+A(x))\)

多项式快速幂

先求\(\ln\),然后乘\(k\),再\(\exp\)回去。

虽然是\(O(n\log n)\)但是常数不知道几个\(\log\)了

开根忘了求可以用常数巨大的\(\exp\)

多项式带余除法(取膜)

\(F(x)=G(x)Q(x)+R(x)\),已知\(F,G\)分别是次数为\(n-1,m-1(n>m)\)的多项式,\(Q\)是次数为\(n-m\)的多项式,\(R\)次数小于\(m-1\)。求\(Q,R\)

因为结论很好记就直接记结论了。

\(Q^R=F^R{G^R}^{-1}\mod x^{n-m}\)

\(R=F-GQ\)

就做完了。


板子,vector写的,没卡常警告

//================多项式板子部分===================
#define mod 998244353
#define maxn 262147
#define Gmod 3
#define poly std::vector<int>
il int pow(int x,int y){
int ret=1;
while(y){
if(y&1)ret=1ll*ret*x%mod;
x=1ll*x*x%mod;y>>=1;
}
return ret;
}
int rev[maxn],_lstN,P[maxn],iP[maxn];
il vd ntt(int*A,int N,int t){
for(int i=0;i<N;++i)if(rev[i]>i)std::swap(A[i],A[rev[i]]);
for(int o=1;o<N;o<<=1){
int W=t?P[o]:iP[o];
for(int*p=A;p!=A+N;p+=o<<1)
for(int i=0,w=1;i<o;++i,w=1ll*w*W%mod){
int t=1ll*w*p[i+o]%mod;
p[i+o]=(p[i]-t+mod)%mod;p[i]=(p[i]+t)%mod;
}
}
if(!t){
int inv=pow(N,mod-2);
for(int i=0;i<N;++i)A[i]=1ll*A[i]*inv%mod;
}
}
int N,lg;
il vd setN(int n){
N=1,lg=0;
while(N<n)N<<=1,++lg;
if(N!=_lstN)for(int i=0;i<N;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-1);
}
il vd ntt(poly&a,int t){
static int A[maxn];
for(int i=0;i<a.size();++i)A[i]=a[i];memset(A+a.size(),0,4*(N-a.size()));
ntt(A,N,t);
a.resize(N);
for(int i=0;i<N;++i)a[i]=A[i];
int s=a.size();while(s&&!a[s-1])--s;
a.resize(s);
}
il poly mul(poly a,poly b,int newn=-1){
if(newn==-1)newn=a.size()+b.size()-1;
setN(a.size()+b.size()-1);
ntt(a,1),ntt(b,1);
for(int i=0;i<N;++i)a[i]=1ll*a[i]*b[i]%mod;
ntt(a,0);a.resize(newn);
return a;
}
il poly operator+(poly a,const poly&b){
if(a.size()<b.size())a.resize(b.size());
for(int i=0;i<a.size();++i)if(i<b.size())a[i]=(a[i]+b[i])%mod;
return a;
}
il poly operator-(poly a,const poly&b){
if(a.size()<b.size())a.resize(b.size());
for(int i=0;i<a.size();++i)if(i<b.size())a[i]=(a[i]-b[i]+mod)%mod;
return a;
}
il poly operator*(poly a,int b){
for(auto&i:a)i=1ll*i*b%mod;
return a;
}
il poly qiudao(poly a){
for(int i=0;i<a.size()-1;++i)a[i]=1ll*a[i+1]*(i+1)%mod;
a.erase(a.end()-1);
return a;
}
il poly jifen(poly a){
a.insert(a.begin(),0);
for(int i=1;i<a.size();++i)a[i]=1ll*a[i]*pow(i,mod-2)%mod;
return a;
}
il poly getinv(poly a){
if(a.size()==1)return poly(1,pow(a[0],mod-2));
int n=a.size(),m=a.size()+1>>1;
poly _a(m);
for(int i=0;i<m;++i)_a[i]=a[i];
poly b=getinv(_a);
setN(n+m*2-2);
ntt(a,1);ntt(b,1);
for(int i=0;i<N;++i)a[i]=1ll*a[i]*b[i]%mod*b[i]%mod;
ntt(a,0),ntt(b,0);
a.resize(n);
return b*2-a;
}
il poly getln(poly a,int n=-1){
if(n==-1)n=a.size();
a.resize(n);
return jifen(mul(qiudao(a),getinv(a),n));
}
il poly getexp(poly a){
if(a.size()==1)return a[0]=1,a;
int n=a.size(),m=a.size()+1>>1;
poly _a(m);
for(int i=0;i<m;++i)_a[i]=a[i];
poly b=getexp(_a);
return mul(b,poly(1,1)-getln(b,a.size())+a,a.size());
}
il poly operator^(poly a,int b){
int n=a.size();
a=getexp(getln(a)*b);a.resize(n);
return a;
}
il poly operator%(poly a,poly b){
int n=a.size(),m=b.size();
if(n<m)return a;
std::reverse(a.begin(),a.end());
std::reverse(b.begin(),b.end());
b.resize(n);
poly c=mul(a,getinv(b),n-m+1);
std::reverse(a.begin(),a.end());
b.resize(m);std::reverse(b.begin(),b.end());
std::reverse(c.begin(),c.end());
a=a-mul(b,c);
int s=a.size();while(s&&!a[s-1])--s;
a.resize(s);
return a;
}
il poly sqrt(poly a){
if(a.size()==1)return a;
int n=a.size(),m=a.size()+1>>1;
poly _a(m);
for(int i=0;i<m;++i)_a[i]=a[i];
poly b=sqrt(_a);b.resize(n);
return (b+mul(a,getinv(b),n))*(mod+1>>1);
}
il vd poly_init(){
int G=Gmod,iG=pow(G,mod-2);
for(int i=1;i<maxn;i<<=1)P[i]=pow(G,(mod-1)/(i<<1)),iP[i]=pow(iG,(mod-1)/(i<<1));
}
struct _poly_auto_init{_poly_auto_init(){poly_init();}}_auto_init;
//End==============多项式板子部分===================

多项式总结&多项式板子的更多相关文章

  1. 【Cogs2187】帕秋莉的超级多项式(多项式运算)

    [Cogs2187]帕秋莉的超级多项式(多项式运算) 题面 Cogs 题解 多项式运算模板题 只提供代码了.. #include<iostream> #include<cstdio& ...

  2. 【xsy2978】Product of Roots 生成函数+多项式ln+多项式exp

    题目大意:给你两个多项式$f(x)$和$g(x)$,满足$f(x)=\prod\limits_{i=1}^{n}(a_i+1)$,$g(x)=\prod\limits_{i=1}^{m}(b_i+1) ...

  3. 洛谷P4726 【模板】多项式指数函数(多项式exp)

    题意 题目链接 Sol 多项式exp,直接套泰勒展开的公式 \(F(x) = e^{A(x)}\) 求个导\(F'(x) = A(x)\) 我们要求的就是\(G(f(x)) = lnF(x) - A( ...

  4. 【XSY2730】Ball 多项式exp 多项式ln 多项式开根 常系数线性递推 DP

    题目大意 一行有\(n\)个球,现在将这些球分成\(k\) 组,每组可以有一个球或相邻两个球.一个球只能在至多一个组中(可以不在任何组中).求对于\(1\leq k\leq m\)的所有\(k\)分别 ...

  5. MATLAB多项式及多项式拟合

    多项式均表示为数组形式,数组元素为多项式降幂系数 1.      polyval函数 求多项式在某一点或某几个点的值. p = [1,1,1];%x^2+x+1 x = [-1,0,1];y = po ...

  6. luogu P4726 【模板】多项式指数函数 多项式 exp 牛顿迭代 泰勒展开

    LINK:多项式 exp 做多项式的题 简直在嗑药. 前置只是 泰勒展开 这个东西用于 对于一个函数f(x) 我们不好得到 其在x处的取值. 所以另外设一个函数g(x) 来在x点处无限逼近f(x). ...

  7. 洛谷 P6667 - [清华集训2016] 如何优雅地求和(下降幂多项式,多项式)

    题面传送门 wjz:<如何优雅地 AK NOI> 我:如何优雅地爆零 首先,按照这题总结出来的一个小套路,看到多项式与组合数结合的题,可以考虑将普通多项式转为下降幂多项式,因为下降幂和组合 ...

  8. 洛谷P5245 【模板】多项式快速幂(多项式ln 多项式exp)

    题意 题目链接 Sol \(B(x) = \exp(K\ln(A(x)))\) 做完了... 复杂度\(O(n\log n)\) // luogu-judger-enable-o2 // luogu- ...

  9. 洛谷P4725 【模板】多项式对数函数(多项式ln)

    题意 题目链接 Sol 这个不用背XD 前置知识: \(f(x) = ln(x), f'(x) = \frac{1}{x}\) \(f(g(x)) = f'(g(x)) g'(x)\) 我们要求的是\ ...

随机推荐

  1. Gradle 翻译 tips and recipes 使用技巧 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. Zipkin存储Sleuth信息实现调用链追踪的几种方法

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/alva_xu/article/detail ...

  3. C# 对象集合初始化

    一.自动实现的属性 public class Person { // C# 3之前我们定义属性时,一般会像下面这样去定义 // 首先会先定义私有字段,再定义属性来对字段进行访问 //private s ...

  4. 如何在ArcGIS饼状图中下方添加文字

    内容源自:ArcGIS10.2基础教程(丁华) 书上要求在统计图的饼状图下方显示“总面积组成”,以及图例是只显示文字. 该如何操作呢? 其实就是在高级属性中选择标题-副标题-显示“总面积组成”即可 而 ...

  5. Java GC的工作原理详解

    JVM学习笔记之JVM内存管理和JVM垃圾回收的概念,JVM内存结构由堆.栈.本地方法栈.方法区等部分组成,另外JVM分别对新生代下载地址  和旧生代采用不同的垃圾回收机制. 首先来看一下JVM内存结 ...

  6. Linux中打开文件显示行号相关命令

    一.显示行号 :set number 或 :set nu 二.取消显示行号 :set nu! 三.每次打开显示行号 修改vi ~/.vimrc 文件,添加:set number

  7. golang的channel实现

    golang的channel实现位于src/runtime/chan.go文件.golang中的channel对应的结构是: // Invariants: // At least one of c.s ...

  8. linux下的 c 和 c++ 开发工具及linux内核开发工具

    https://opensource.com/article/18/6/embedded-linux-build-tools https://github.com/luong-komorebi/Awe ...

  9. linux设备驱动程序--串行通信驱动框架分析

    linux 串行通信接口驱动框架 在学习linux内核驱动时,不论是看linux相关的书籍,又或者是直接看linux的源码,总是能在linux中看到各种各样的框架,linux内核极其庞杂,linux各 ...

  10. HTML&CSS基础-html标签的实体

    HTML&CSS基础-html标签的实体 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.HTML源代码 <!DOCTYPE html> <html&g ...