[模板]多项式全家桶小记(求逆,开根,ln,exp)

前言

这里的全家桶目前只包括了ln,exp,sqrtln,exp,sqrtln,exp,sqrt。还有一些类似于带余数模,快速幂之类用的比较少的有时间再更,NTTNTTNTT这种前置知识这里不多说。

还有一些基本的导数和微积分内容要了解,建议不懂的可以先去翻翻高二数学书。

之后多项式算法基本是一环扣一环的,所以前面的看不懂对于后面的理解会造成很大影响。

本博客涉及内容偏浅


Tips

这里是一些我个人的模板书写习惯

  • 习惯相关的问题:默认将读入的nnn变为222的整数次幂形式,目前为止这样的做法都不会影响正确性
  • 正确性相关的问题:模板书写应满足使用的中间变量不重复,如在求lnlnln和逆元时不应该使用重复的中间变量(可能会导致信息丢失)
  • 正确性相关的问题:在每次进行任意操作前应保证在操作值域内不会有上次的信息参与(要清零)

参考资料

  • [command-block]NTT与多项式全家桶
  • [CYJian]浅谈多项式
  • [隔壁的张栩嘉]浅谈牛顿迭代法
  • 洛谷各模板题解

正题

文章目录

    • 前言
    • Tips
    • 参考资料
  • 正题
    • 多项式求逆
      • 题目大意
      • 分析
      • code
    • 多项式导数相关
      • 多项式求导
      • 多项式积分
      • 多项式复合
      • 泰勒公式
      • 牛顿迭代
      • 多项式复合零点
    • 多项式开根
      • 题目大意
      • 分析
      • code
    • 多项式ln
      • 题目大意
      • 分析
      • code
    • 多项式exp
      • 题目大意
      • 解题思路
      • code


多项式求逆

题目大意

给出一个多项式FFF,求出一个GGG使得
F(x)∗G(x)≡1(modxn)F(x)*G(x)\equiv1(mod\ x^n)F(x)G(x)1(mod xn)

分析

利用经典的倍增思想,假设我们已知多项式G′(x)G'(x)G(x)满足
F(x)G′(x)≡1(modxn2)F(x)G'(x)\equiv1(mod\ x^{\frac{n}{2}})F(x)G(x)1(mod x2n)
又有
F(x)G(x)≡1(modxn2)F(x)G(x)\equiv 1(mod\ x^{\frac{n}{2}})F(x)G(x)1(mod x2n)
就有了
F(x)(G(x)−G′(x))≡0(modxn2)⇒G(x)−G′(x)≡0(modxn2)F(x)(G(x)-G'(x))\equiv 0(mod\ x^{\frac{n}{2}})\Rightarrow G(x)-G'(x)\equiv 0(mod\ x^{\frac{n}{2}})F(x)(G(x)G(x))0(mod x2n)G(x)G(x)0(mod x2n)
然后两边同时平方,后面的模数同理也要平方
G(x)2−2G(x)G′(x)+G′(x)2≡0(modxn)G(x)^2-2G(x)G'(x)+G'(x)^2\equiv 0(mod\ x^n)G(x)22G(x)G(x)+G(x)20(mod xn)
再乘上一个F(x)F(x)F(x)
F(x)G(x)2−2F(x)G(x)G′(x)+F(x)G′(x)2≡0(modxn)F(x)G(x)^2-2F(x)G(x)G'(x)+F(x)G'(x)^2\equiv 0(mod\ x^n)F(x)G(x)22F(x)G(x)G(x)+F(x)G(x)20(mod xn)
又因为F(x)G(x)≡1(modxn)F(x)G(x)\equiv 1(mod\ x^n)F(x)G(x)1(mod xn),所以就有
G(x)−2G′(x)+F(x)G′(x)2≡0(modxn)⇒G(x)≡2G′(x)−F(x)G′(x)2(modxn)G(x)-2G'(x)+F(x)G'(x)^2\equiv0(mod\ x^n)\Rightarrow G(x)\equiv 2G'(x)-F(x)G'(x)^2(mod\ x^n)G(x)2G(x)+F(x)G(x)20(mod xn)G(x)2G(x)F(x)G(x)2(mod xn)
然后倍增就好了,时间复杂度是类似于T(n)=T(n2)+nlog⁡nT(n)=T(\frac{n}{2})+n\log nT(n)=T(2n)+nlogn的形式所以是O(nlog⁡n)O(n\log n)O(nlogn)的。

code

比较远古的代码所以码风有点不同

// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const ll N=1e6+100,XJQ=998244353,G=3,Gi=332748118;
const double Pi=acos(-1);
ll n,m,l,a[N<<2],b[N<<2],c[N<<2],r[N<<2];
ll power(ll x,ll b)
{ll ans=1;while(b){if(b&1) ans=ans*x%XJQ;x=x*x%XJQ;b>>=1;}return ans;
}
void ntt(ll *f,ll n,ll op)
{for(ll i=0;i<n;i++)if(i<r[i])swap(f[i],f[r[i]]);for(ll p=2;p<=n;p<<=1){ll len=p>>1,tmp=power(G,(XJQ-1)/p);for(ll k=0;k<n;k+=p){ll buf=1;for(ll i=k;i<k+len;i++){ll tt=buf*f[len+i]%XJQ;f[len+i]=(f[i]-tt+XJQ)%XJQ;f[i]=(f[i]+tt)%XJQ;buf=buf*tmp%XJQ;}}}if(op==1) return;int inv=power(n,XJQ-2);reverse(f+1,f+n);for(int i=0;i<n;i++) f[i]=f[i]*inv%XJQ;
}
void work(ll *a,ll *b,ll l)
{if(l==1){b[0]=power(a[0],XJQ-2);return;}work(a,b,(l+1)>>1);ll cnt;for(cnt=1;cnt<(l<<1);cnt<<=1);for(ll i=1;i<cnt;i++)r[i]=(r[i>>1]>>1)|((i&1)?cnt>>1:0);for(ll i=0;i<l;i++) c[i]=a[i];for(ll i=l;i<cnt;i++) c[i]=0;ntt(c,cnt,1);ntt(b,cnt,1);for(ll i=0;i<cnt;i++)b[i]=(2-b[i]*c[i]%XJQ+XJQ)%XJQ*b[i]%XJQ;ntt(b,cnt,-1);for(ll i=l;i<cnt;i++) b[i]=0;
}
int main()
{scanf("%lld",&n);for(ll i=0;i<n;i++)scanf("%lld",&a[i]);work(a,b,n);for(ll i=0;i<n;i++)printf("%lld ",b[i]);
}

多项式导数相关

后面就要开始用到高二的知识了

多项式求导

后面定义f′f'f表示多项式fff的求导,定义ai=f(x)[i]a_i=f(x)[i]ai=f(x)[i],那么有
f′(x)=∑i=0nai+1(i+1)xif'(x)=\sum_{i=0}^na_{i+1}(i+1)x^if(x)=i=0nai+1(i+1)xi
大体就是把所有位乘上iii再往前移动,对导数有了解的话应该能理解,这里就不给出推导了

多项式积分

同理定义ai=f(x)[i]a_i=f(x)[i]ai=f(x)[i],那fff的积分ggg就有
g(x)=∑i=0nai−1ixig(x)=\sum_{i=0}^n\frac{a_{i-1}}{i}x^ig(x)=i=0niai1xi
和上面同理,需要知道积分和求导是逆运算。

多项式复合

定义复合函数
F(G(x))=∑i=0F[i]G(x)iF(G(x))=\sum_{i=0}F[i]G(x)^iF(G(x))=i=0F[i]G(x)i
看上去没什么用,之后再说

泰勒公式

这里开始就暂时不和多项式有多挂钩了。
f(x)=lim⁡n→∞∑i=0nf(n)(x0)i!(x−x0)i+Rn(x)f(x)=\lim_{n\to \infty}\sum_{i=0}^{n}\frac{f^{(n)}(x_0)}{i!}(x-x_0)^i+R_n(x)f(x)=nlimi=0ni!f(n)(x0)(xx0)i+Rn(x)
其中f(n)f^{(n)}f(n)表示fffnnn阶求导,Rn(x)R_n(x)Rn(x)是余项。
看上去没有什么用,是牛迭的基础,可以直接记牛迭的结论。
到时候会有泰勒公式的常用写法

牛顿迭代

这里就不用泰勒公式的推导了,直接感性点理解快速过一下。
我们知道导数
f′(x)=lim⁡Δx→0f(x+Δx)−f(x)Δxf'(x)=\lim_{\Delta x\to0}\frac{f(x+\Delta x)-f(x)}{\Delta x}f(x)=Δx0limΔxf(x+Δx)f(x)
是可以理解为求某个函数在(x,f(x))(x,f(x))(x,f(x))处的切点,而牛顿迭代正是利用这个原理求函数的近似零点,可以先看一张生动的图(来自维基百科)。
在这里插入图片描述
就是先找一个点(x,f(x))(x,f(x))(x,f(x)),然后求它在函数图像上的切线,之后这条切线与xxx有交的位置x′x'x再带入xxx之后继续这个过程。

这个过程中求得的xxx在不断逼近原点,这样就可以求出一个函数000点的近似解。

当然牛顿迭代显然并不是对所有函数都适用的,但是对于我们需要解决的多项式问题来说足够了。

然后要上泰勒公式了
f(x)=lim⁡n→∞∑i=0nf(n)(x0)i!(x−x0)i+Rn(x)f(x)=\lim_{n\to \infty}\sum_{i=0}^{n}\frac{f^{(n)}(x_0)}{i!}(x-x_0)^i+R_n(x)f(x)=nlimi=0ni!f(n)(x0)(xx0)i+Rn(x)
这里只拿i=1i=1i=1的情况来展开一下,再定义一个ϕ(x)≈f(x)\phi(x)\approx f(x)ϕ(x)f(x)就是
f(x)≈ϕ(x)=f′(x0)(x−x0)−f(x0)f(x)\approx \phi(x)=f'(x_0)(x-x_0)-f(x_0)f(x)ϕ(x)=f(x0)(xx0)f(x0)
然后如果求f(x)=0f(x)=0f(x)=0就是近似的求ϕ(x)=0\phi(x)=0ϕ(x)=0也就是
f′(x0)(x−x0)−f(x0)=0f'(x_0)(x-x_0)-f(x_0)=0f(x0)(xx0)f(x0)=0
就有
x=x0−f(x0)f′(x0)⇒xn+1=xn−f(xn)f′(xn)x=x_0-\frac{f(x_0)}{f'(x_0)}\Rightarrow x_{n+1}=x_{n}-\frac{f(x_n)}{f'(x_n)}x=x0f(x0)f(x0)xn+1=xnf(xn)f(xn)
这个递推式子。

然后就可以快速近似求解了。

多项式复合零点

那么现在就是牛顿迭代的实战时间了,题目是给出一个多项式G(x)G(x)G(x),要求求出一个f(x)f(x)f(x)使得G(f(x))≡0(modxn)G(f(x))\equiv 0(mod\ x^n)G(f(x))0(mod xn)

拿多项式来泰勒展开推导或者直接用上面的牛迭结论。设ftf_tft满足G(ft)≡0(modx2t)G(f_t)\equiv 0(mod\ x^{2^t})G(ft)0(mod x2t),那么就有结论
ft≡ft−1−G(ft−1)G′(ft−1)(modx2t)f_t\equiv f_{t-1}-\frac{G(f_{t-1})}{G'(f_{t-1})}(mod\ {x^{2^t}})ftft1G(ft1)G(ft1)(mod x2t)
这里还是推导一下吧,先把fff给泰勒展开了(这里换成了一个比较常用的写法)
G(ft)≡G(ft−1)+∑i=1∞G(i)(ft−1)i!∗(ft−ft−1)i(modx2t)G(f_t)\equiv G(f_{t-1})+\sum_{i=1}^\infty\frac{G^{(i)}(f_{t-1})}{i!}*(f_t-f_{t-1})^i(mod\ x^{2^t})G(ft)G(ft1)+i=1i!G(i)(ft1)(ftft1)i(mod x2t)
又因为G(ft−1)≡0(modx2t−1)G(f_{t-1})\equiv 0(mod\ x^{2^{t-1}})G(ft1)0(mod x2t1)G(ft)≡0(modx2t)G(f_t)\equiv 0(mod\ x^{2^t})G(ft)0(mod x2t)。所以ft−ft−1f_t-f_{t-1}ftft1的前2t−12^{t-1}2t1项都是000,那么(ft−ft−1)2(f_t-f_{t-1})^2(ftft1)2的前2t2^t2t都是0,也就当i≥2i\geq 2i2的时候后面的项都被模掉了,所以式子就变得很简单了。
G(ft)≡G(ft−1)+G′(ft−1)∗(ft−ft−1)(modx2t)G(f_t)\equiv G(f_{t-1})+G'(f_{t-1})*(f_t-f_{t-1})(mod\ x^{2^t})G(ft)G(ft1)+G(ft1)(ftft1)(mod x2t)
G(ft)=0G(f_t)=0G(ft)=0带入就有
ft=ft−1−G(ft−1)G′(ft−1)(modx2t)f_t=f_{t-1}-\frac{G(f_{t-1})}{G'(f_{t-1})}(mod\ x^{2^t})ft=ft1G(ft1)G(ft1)(mod x2t)
式子到这里就得根据具体情况化简了,然后练练手?


多项式开根

题目大意

给出一个多项式FFF,求一个多项式GGG满足
G(x)2=F(x)(modxn)G(x)^2=F(x)(mod\ x^{n})G(x)2=F(x)(mod xn)

分析

下面的GGG和上面的要求的GGG不同
如果我们求出一个多项式G(f)=f2−F(x)G(f)=f^2-F(x)G(f)=f2F(x)。如果G(f)≡0(modxn)G(f)\equiv 0(mod\ x^n)G(f)0(mod xn)的解就是f(x)≡F(x)(modxn)f(x)\equiv \sqrt{F(x)}(mod\ x^n)f(x)F(x)(mod xn)的解了。
之后直接代前面多项式零点求值的东西就有
ft=ft−1−G(ft−1)G′(ft−1)⇒ft=ft−1−ft−12−F(x)2ft−1f_t=f_{t-1}-\frac{G(f_{t-1})}{G'(f_{t-1})}\Rightarrow f_t=f_{t-1}-\frac{f_{t-1}^2-F(x)}{2f_{t-1}}ft=ft1G(ft1)G(ft1)ft=ft12ft1ft12F(x)
嗯,那个2ft−12f_{t-1}2ft1是对GGG手动求导的结果
时间复杂度也是类T(n)=T(n2)+nlog⁡nT(n)=T(\frac{n}{2})+n\log nT(n)=T(2n)+nlogn的形式所以还是O(nlog⁡n)O(n\log n)O(nlogn)

code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=6e5+10,P=998244353,inv2=(P+1)/2;
ll n,a[N],b[N],r[N];
ll t1[N],t2[N],t3[N],t4[N];
ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans;
}
ll GetL(ll len){ll n=1;while(n<=len)n<<=1;for(ll i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)?(n>>1):0);return n;
}
void NTT(ll *f,ll n,ll op){for(ll i=0;i<n;i++)if(i<r[i])swap(f[i],f[r[i]]);for(ll p=2;p<=n;p<<=1){ll len=p>>1,tmp=power(3,(P-1)/p);if(op==-1)tmp=power(tmp,P-2);for(ll k=0;k<n;k+=p){ll buf=1;for(ll i=k;i<k+len;i++){ll tt=f[i+len]*buf%P;f[i+len]=(f[i]-tt+P)%P;f[i]=(f[i]+tt)%P;buf=buf*tmp%P;}}}if(op==-1){ll invn=power(n,P-2);for(ll i=0;i<n;i++)f[i]=f[i]*invn%P;}return;
}
void GetInv(ll *f,ll *g,ll n){if(n==1){g[0]=power(f[0],P-2);return;}GetInv(f,g,n>>1);ll l=GetL(n);for(ll i=0;i<n;i++)t1[i]=f[i],t2[i]=g[i];for(ll i=n;i<l;i++)t1[i]=t2[i]=0;NTT(t1,l,1);NTT(t2,l,1);for(ll i=0;i<l;i++)t1[i]=t1[i]*t2[i]%P*t2[i]%P;NTT(t1,l,-1);for(ll i=0;i<n;i++)g[i]=(2*g[i]-t1[i]+P)%P;return;
}
void Sqrt(ll *f,ll *g,ll n){if(n==1){g[0]=1;return;}Sqrt(f,g,n>>1);ll l=GetL(n<<1);for(ll i=0;i<n;i++)t3[i]=f[i],t4[i]=0;for(ll i=n;i<l;i++)t3[i]=t4[i]=0;GetInv(g,t4,n);l=GetL(n<<1);NTT(t3,l,1);NTT(t4,l,1);for(ll i=0;i<l;i++)t3[i]=t3[i]*t4[i]%P;NTT(t3,l,-1);for(ll i=0;i<n;i++)g[i]=(g[i]+t3[i])*inv2%P;return;
}
signed main()
{scanf("%lld",&n);for(ll i=0;i<n;i++)scanf("%lld",&a[i]);ll m=GetL(n);Sqrt(a,b,m);for(ll i=0;i<n;i++)printf("%lld ",b[i]);return 0;
}

多项式ln

题目大意

给出一个多项式FFF,求一个多项式GGG满足
G(x)≡ln(F(x))(modxn)G(x)\equiv ln(F(x))(mod\ x^n)G(x)ln(F(x))(mod xn)

分析

这个题不用牛顿迭代,对GGG求个导,因为是复合函数直接展开
G′(x)≡ln′(F(x))∗F′(x)(modxn)⇒G′(x)≡F′(x)F(x)(modxn)G'(x)\equiv ln'(F(x))*F'(x)(mod\ x^n)\Rightarrow G'(x)\equiv\frac{F'(x)}{F(x)}(mod\ x^n)G(x)ln(F(x))F(x)(mod xn)G(x)F(x)F(x)(mod xn)
这个推导要用到的有ln′(x)=1xln'(x)=\frac{1}{x}ln(x)=x1

就是算F′(x)F(x)\frac{F'(x)}{F(x)}F(x)F(x)再积分就好了
时间复杂度O(nlog⁡n)O(n\log n)O(nlogn)

code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=4e5+10,P=998244353;
ll n,r[N],f[N],g[N];
ll t1[N],t2[N],t3[N],t4[N];
ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans;
}
ll GetL(ll len){ll n=1;while(n<=len)n<<=1;for(ll i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)?(n>>1):0);return n;
}
void NTT(ll *f,ll n,ll op){for(ll i=0;i<n;i++)if(i<r[i])swap(f[i],f[r[i]]);for(ll p=2;p<=n;p<<=1){ll len=p>>1,tmp=power(3,(P-1)/p);if(op==-1)tmp=power(tmp,P-2);for(ll k=0;k<n;k+=p){ll buf=1;for(ll i=k;i<k+len;i++){ll tt=f[i+len]*buf%P;f[i+len]=(f[i]-tt+P)%P;f[i]=(f[i]+tt)%P;buf=buf*tmp%P;}}}if(op==-1){ll invn=power(n,P-2);for(ll i=0;i<n;i++)f[i]=f[i]*invn%P;}return;
}
void GetInv(ll *f,ll *g,ll n){if(n==1){g[0]=power(f[0],P-2);return;}GetInv(f,g,n>>1);ll m=GetL(n);for(ll i=0;i<n;i++)t1[i]=f[i],t2[i]=g[i];for(ll i=n;i<m;i++)t1[i]=t2[i]=0;NTT(t1,m,1);NTT(t2,m,1);for(ll i=0;i<m;i++)t1[i]=t1[i]*t2[i]%P*t2[i]%P;NTT(t1,m,-1);for(ll i=0;i<n;i++)g[i]=(2*g[i]-t1[i]+P)%P;return;
}
void GetD(ll *f,ll *g,ll n){for(ll i=0;i<n;i++)g[i]=f[i+1]*(i+1)%P;g[n-1]=0;return;
}
void GetJ(ll *f,ll *g,ll n){for(ll i=1;i<n;i++)g[i]=f[i-1]*power(i,P-2)%P;g[0]=0;return;
}
void GetLn(ll *f,ll *g,ll n){n=GetL(n);GetD(f,t3,n);GetInv(f,t4,n);n=GetL(n);NTT(t3,n,1);NTT(t4,n,1);for(ll i=0;i<n;i++)t3[i]=t3[i]*t4[i]%P;NTT(t3,n,-1);GetJ(t3,g,n);return;
}
signed main()
{scanf("%lld",&n);for(ll i=0;i<n;i++)scanf("%lld",&f[i]);GetLn(f,g,n);for(ll i=0;i<n;i++)printf("%lld ",g[i]);return 0;
}

多项式exp

题目大意

给出多项式FFF,求一个多项式GGG满足
G(x)≡eF(x)(modxn)G(x)\equiv e^{F(x)}(mod\ x^n)G(x)eF(x)(mod xn)

解题思路

这个应该是最麻烦的了,和开根一样的思路
定义一个复合函数G(f)=ln(f)−F(x)G(f)=ln(f)-F(x)G(f)=ln(f)F(x)那么当G(f)=0G(f)=0G(f)=0的解就是答案了。
然后同理直接上倍增加泰勒展开
ft≡ft−1−G(ft−1)G′(ft−1)(modx2t)⇒ft≡ft−1−(ln(ft−1)−F(x))∗ft−1(modx2t)f_t\equiv f_{t-1}-\frac{G(f_{t-1})}{G'(f_{t-1})}(mod\ x^{2^t})\Rightarrow f_t\equiv f_{t-1}-(ln(f_{t-1})-F(x))*f_{t-1}(mod\ x^{2^t})ftft1G(ft1)G(ft1)(mod x2t)ftft1(ln(ft1)F(x))ft1(mod x2t)
然后时间复杂度依旧是T(n)=T(n2)+nlog⁡nT(n)=T(\frac{n}{2})+n\log nT(n)=T(2n)+nlogn,所以还是O(nlog⁡n)O(n\log n)O(nlogn)
在这里插入图片描述

然后上个lnlnln和求逆就好了


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=8e5+10,P=998244353;
ll n,m,r[N],a[N],b[N];
ll t1[N],t2[N],t3[N],t4[N],t5[N],t6[N];
ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans;
}
void GetL(ll len){n=1;while(n<=len)n<<=1;for(ll i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)?(n>>1):0);return;
}
void NTT(ll *f,ll op){for(ll i=0;i<n;i++)if(i<r[i])swap(f[i],f[r[i]]);for(ll p=2;p<=n;p<<=1){ll len=p>>1,tmp=power(3,(P-1)/p);if(op==-1)tmp=power(tmp,P-2);for(ll k=0;k<n;k+=p){ll buf=1;for(ll i=k;i<k+len;i++){ll tt=f[i+len]*buf%P;f[i+len]=(f[i]-tt+P)%P;f[i]=(f[i]+tt)%P;buf=buf*tmp%P;}}}if(op==-1){ll invn=power(n,P-2);for(ll i=0;i<n;i++)f[i]=f[i]*invn%P;}return;
}
void GetInv(ll *f,ll *g,ll m){if(m==1){g[0]=power(f[0],P-2);return;}GetInv(f,g,m>>1);GetL(m);for(ll i=0;i<m;i++)t1[i]=f[i],t2[i]=g[i];for(ll i=m;i<n;i++)t1[i]=t2[i]=0;NTT(t1,1);NTT(t2,1);for(ll i=0;i<n;i++)t1[i]=t1[i]*t2[i]%P*t2[i]%P;NTT(t1,-1);for(ll i=0;i<m;i++)g[i]=(2*g[i]-t1[i]+P)%P;return;
}
void GetD(ll *f,ll *g,ll n){for(ll i=0;i<n-1;i++)g[i]=f[i+1]*(i+1)%P;g[n-1]=0;return;
}
void GetJ(ll *f,ll *g,ll n){for(ll i=1;i<n;i++)g[i]=f[i-1]*power(i,P-2)%P;g[0]=0;return;
}
void GetLn(ll *f,ll *g,ll m){GetL(m);GetD(f,t3,n);GetInv(f,t4,n);GetL(m);GetL(n);NTT(t3,1);NTT(t4,1);for(ll i=0;i<n;i++)t3[i]=t3[i]*t4[i]%P;NTT(t3,-1);GetJ(t3,g,n);for(int i=0;i<n;i++)t3[i]=t4[i]=0;return;
}
void GetExp(ll *f,ll *g,ll m){if(m==1){g[0]=1;return;}GetExp(f,g,m>>1);GetLn(g,t5,m);GetL(m);for(ll i=0;i<m;i++)t6[i]=f[i];for(ll i=m;i<n;i++)t5[i]=t6[i]=0;NTT(t5,1);NTT(t6,1);NTT(g,1);for(ll i=0;i<n;i++)g[i]=g[i]*(1-t5[i]+t6[i]+P)%P;NTT(g,-1);for(ll i=m;i<n;i++)g[i]=0;return;
}
signed main()
{scanf("%lld",&m);for(ll i=0;i<m;i++)scanf("%lld",&a[i]);GetL(m);GetExp(a,b,n);for(ll i=0;i<m;i++)printf("%lld ",b[i]);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客网【每日一题】7月21日题目精讲—区间权值

来源&#xff1a;牛客网&#xff1a; 区间权值 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 1048576K&#xff0c;其他语言2097152K 64bit IO Format: %lld题目描述 输入描述: 第一行一个正整数 n 第二行 n 个正整数 a1…an 第三行 n 个正…

C# 函数式编程:LINQ

一直以来&#xff0c;我以为 LINQ 是专门用来对不同数据源进行查询的工具&#xff0c;直到我看了这篇十多年前的文章&#xff0c;才发现 LINQ 的功能远不止 Query。这篇文章的内容比较高级&#xff0c;主要写了用 C# 3.0 推出的 LINQ 语法实现了一套“解析器组合子&#xff08;…

2020牛客暑期多校训练营(第六场)

2020牛客暑期多校训练营&#xff08;第六场&#xff09; 额&#xff0c;睡了一下午&#xff0c;直接错过了比赛。。。 文章目录A African Sort题意&#xff1a;题解&#xff1a;代码&#xff1a;B Binary VectorC Combination of Physics and Maths题意&#xff1a;题解&#x…

P4001-[ICPC-Beijing 2006]狼抓兔子【对偶图】

正题 题目链接:https://www.luogu.com.cn/problem/P4001 题目大意 给出一个类似于 的网格图&#xff0c;求起点到终点的最小割。 解题思路 最小割直接跑网络流&#xff0c;然后发现dinicdinicdinic都过不了。&#xff08;好像加点玄学优化就能过&#xff09; 然后上点科技…

私有云方案——利用阿里云云解析实现DDNS

各位都是程序员&#xff0c;工作中是不是遇到个类似情况。在家里研究的一些开源代码或写的一些demo或试验代码&#xff0c;在工作中正好需要参考一下&#xff0c;但是在家里的电脑上。虽然这些都可以用云盘/网盘之类的来完成&#xff0c;源代码也可以托管到源码平台。但是这些都…

2020年首届算法竞赛网络挑战赛直播讲解课程

比赛链接 菜鸡的我&#xff0c;第四名。。 A 矛盾激化 题意 给定地图&#xff0c;这个地图有两个出口&#xff0c;现在我们需要求出从所有点到任意一个出口的距离中的最短路径的最大值 本题为输出答案题&#xff0c;给定你一种情况&#xff0c;然后输出它的答案 题解 如果…

光荣与梦想 | XMove动作捕捉系统(一)

今年春节回到老家&#xff0c;翻出了2011年春节时焊电路用过的松香和和硬盘角落里的代码。感慨万分&#xff0c;遂有此文。文章过长&#xff0c;分为两部分&#xff0c;本文为2010-2011年&#xff0c;XMove从第一代到第三代的故事。诞生于考研的第一代保研尚未确定&#xff0c;…

大型科技公司架构:中台模式的爱与恨

大型企业面对快速变化的市场形势&#xff0c;需要有像创业公司一样快速的反应能力。然而由于复杂的人员和层级关系&#xff0c;大企业做到“拥抱变化”是很困难的。传统以职能部门分治的树状组织架构&#xff0c;若一个底层员工有个好点子&#xff0c;就不得不自下而上说服管理…

牛客网 【每日一题】7月27日题目精讲—乌龟棋

来源&#xff1a;牛客网&#xff1a; 乌龟棋 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 131072K&#xff0c;其他语言262144K 64bit IO Format: %lld文章目录乌龟棋题目描述题解&#xff1a;代码&#xff1a;题目描述 小明过生日的时候&…

【费用流】摘取作物(jozj 3447)

正题 jozj 3447 题目大意 给你一个n*m的矩阵&#xff0c;每个位置有一个数&#xff0c;每一行每一列都只能选两个数&#xff0c;问你所选数字之和最大是多少 解题思路 对于该矩阵&#xff0c;我们可以建立一个网络图&#xff08;如下图&#xff09; 对于每一行建立建立一个…

如何在.NET Core控制台程序中使用依赖注入

背景介绍依赖注入(Dependency Injection), 是面向对象编程中的一种设计原则&#xff0c;可以用来减低代码之间的耦合度。在.NET Core MVC中我们可以在Startup.cs文件的ConfigureService方法中使用服务容器IServiceCollection注册接口及其实现类的映射。例如&#xff0c;当我们需…

牛客网 【每日一题】7月24日题目精讲—小A的柱状图

链接&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;小A的柱状图时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 柱状图是有一些宽度相等的矩形下端对齐以后…

在asp.net core2.1中添加中间件以扩展Swashbuckle.AspNetCore3.0支持简单的文档访问权限控制...

Swashbuckle.AspNetCore3.0 介绍一个使用 ASP.NET Core 构建的 API 的 Swagger 工具。直接从您的路由&#xff0c;控制器和模型生成漂亮的 API 文档&#xff0c;包括用于探索和测试操作的 UI。项目主页&#xff1a;https://github.com/domaindrivendev/Swashbuckle.AspNetCore划…

牛客网【每日一题】7月29日题目精讲—Max Power

来源&#xff1a;牛客网&#xff1a; Max Power 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 32768K&#xff0c;其他语言65536K 64bit IO Format: %lld题目描述 小卤蛋刚把dnf的技能点重新洗了一遍,现在他要重新加点,假设他的技能树一共有…

Swashbuckle.AspNetCore3.0的二次封装与使用

关于 Swashbuckle.AspNetCore3.0一个使用 ASP.NET Core 构建的 API 的 Swagger 工具。直接从您的路由&#xff0c;控制器和模型生成漂亮的 API 文档&#xff0c;包括用于探索和测试操作的 UI。项目主页&#xff1a;https://github.com/domaindrivendev/Swashbuckle.AspNetCore项…

.NET微服务调查结果

.NET Core就是专门针对模块化的微服务架构而设计, 在2018年国庆时间展开.NET微服务的使用情况&#xff0c;本次调查我们总计收到了来自378个开发者的调查。从落地现状、架构体系、未来趋势等方面对微服务进行了分析。希望能够为传统企业微服务决策、规划和实施提供依据和解决办…

(牛客网)树型dp

树型dp 视频链接 &#xff08;如果想购买网课&#xff0c;可以用我的邀请码&#xff09; 用我的链接购买&#xff0c;我再反你10&#xff0c;一共花54多值 购买链接 不放心可以先加我好友2830872914 总试题链接 文章目录树型dp例题NC15033 小G有一个大树NC511788 没有上司的舞…

Node 源项目定制化、打包并使用全过程讲解

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是全栈工…

.Net Core中的Api版本控制

原文链接&#xff1a;API Versioning in .Net Core作者&#xff1a;Neel Bhatt简介Api的版本控制是Api开发中经常遇到的问题, 在大部分中大型项目都需要使用到Api的版本控制在本篇博客中&#xff0c;我们将说明一下如何在.Net Core Api项目中使用Api版本控制。本篇博客中测试项…

Visual Studio 2017 与 Visual Studio for Mac 支持更新

微软在博客中简单介绍了关于 VS 2017 和 VS for Mac 项目的支持计划&#xff1a;https://blogs.msdn.microsoft.com/visualstudio/2018/10/05/visual-studio-2017-and-visual-studio-for-mac-support-updates/。微软表示&#xff0c;在目前努力开发 Visual Studio 2019 的同时&…