洛谷4238:模板多项式求逆——题解
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷4238:模板多项式求逆——题解相关的知识,希望对你有一定的参考价值。
https://www.luogu.org/problemnew/show/P4238
如题所示,对998244353取模。
板子没啥好说的。
讲解看这位大佬:http://blog.miskcoo.com/2015/05/polynomial-inverse
#include<cstdio> #include<cctype> #include<cstring> #include<vector> #include<cmath> #include<algorithm> #include<iostream> using namespace std; typedef long long ll; const ll P=998244353; const int G=3; const int N=4e5+5; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch==\'-\';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } ll qpow(ll a,ll n,ll p){ ll res=1; while(n){ if(n&1)res=res*a%p; a=a*a%p;n>>=1; } return res; } void MTT(ll a[],int n,int on){ for(int i=1,j=n>>1;i<n-1;i++){ if(i<j)swap(a[i],a[j]); int k=n>>1; while(j>=k){j-=k;k>>=1;} if(j<k)j+=k; } for(int i=2;i<=n;i<<=1){ ll res=qpow(G,(P-1)/i,P); for(int j=0;j<n;j+=i){ ll w=1; for(int k=j;k<j+i/2;k++){ ll u=a[k],t=w*a[k+i/2]%P; a[k]=(u+t)%P; a[k+i/2]=(u-t+P)%P; w=w*res%P; } } } if(on==-1){ ll inv=qpow(n,P-2,P); a[0]=a[0]*inv%P; for(int i=1;i<=n/2;i++){ a[i]=a[i]*inv%P; if(i!=n-i)a[n-i]=a[n-i]*inv%P; swap(a[i],a[n-i]); } } } ll t[N]; void inv(int deg,ll a[],ll b[]){ if(deg==1){ b[0]=qpow(a[0],P-2,P); return; } inv((deg+1)>>1,a,b); int n=1; while(n<(deg<<1))n<<=1; for(int i=0;i<deg;i++)t[i]=a[i]; for(int i=deg;i<n;i++)t[i]=0; MTT(t,n,1);MTT(b,n,1); for(int i=0;i<n;i++) b[i]=b[i]*(2-b[i]*t[i]%P+P)%P; MTT(b,n,-1); for(int i=deg;i<n;i++)b[i]=0; } int n; ll a[N],b[N]; int main(){ int n=read(); for(int i=0;i<n;i++)a[i]=read(); int nn=1; while(nn<n)nn<<=1; inv(nn,a,b); for(int i=0;i<n;i++)printf("%lld ",b[i]); puts(""); return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/ +
+++++++++++++++++++++++++++++++++++++++++++
以上是关于洛谷4238:模板多项式求逆——题解的主要内容,如果未能解决你的问题,请参考以下文章