多项式总结&多项式板子

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


多项式乘法(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. 向Spring 容器中注入对象的几种方法

    1.使用@Bean 注解,用于注入第三方 jar 包到SpringIOC容器中. 2.使用 @Import({Order.class, Member.class, MyImportBeanDefini ...

  2. C#高效编程

    一. 使用readonly而不是const const是编译时常量,readonly是运行时常量.如果引用了一个库中的const常量,则在更新了程序集,但应用程序没有重新编译时,运行结果会出错 如程序 ...

  3. oracle 分页sql

    select * from ( SELECT A.*, ROWNUM RN FROM ( SELECT A.*,B.USERPWiD from 测试表2 A left join 测试表3 B on A ...

  4. How to do SSH Tunneling (Port Forwarding)

    How to do SSH Tunneling (Port Forwarding) In this post we will see how ssh works?, what is SSH tunne ...

  5. Python基础知识(四)

    Python基础知识(四) 一丶列表 定义格式: 是一个容器,由 [ ]表示,元素与元素之间用逗号隔开. 如:name=["张三","李四"] 作用: 存储任意 ...

  6. EVM靶机渗透

    前言 靶机下载地址: https://download.vulnhub.com/norzhctf/Basilic.ova 通过渗透靶机来学习相关知识以便提高在真实环境的渗透能力 ==. 安装: 我是用 ...

  7. 大数据系列文章-Hadoop基础介绍(一)

    Hadoop项目背景简介 2003-2004年,Google公开了部分GFS个Mapreduce思想的细节,以此为基础Doug Cutting等人用了2年的业余时间,实现了DFS和Mapreduce机 ...

  8. 【转】golang-defer坑的本质

    本文节选自https://tiancaiamao.gitbooks.io/go-internals/content/zh/03.4.html 作者的分析非常透彻,从问题本质分析,就不会对defer产生 ...

  9. Pyspark中遇到的 java.io.IOException: Not a file 和 pyspark.sql.utils.AnalysisException: 'Table or view not found

    最近执行pyspark时,直接读取hive里面的数据,经常遇到几个问题: 1.  java.io.IOException: Not a file —— 然而事实上文件是存在的,是 hdfs 的默认路径 ...

  10. Codeforces D. Little Elephant and Interval(思维找规律数位dp)

    题目描述: Little Elephant and Interval time limit per test 2 seconds memory limit per test 256 megabytes ...