优化了一下板子,现在luogu多项式求逆模板只需要400ms-
#include<bits/stdc++.h> using namespace std; #define mo 998244353 #define N 300010 #define ll unsigned long long #define pl vector<int> int qp(int x,int y){ int r=1; for(;y;y>>=1,x=1ll*x*x%mo) if(y&1)r=1ll*r*x%mo; return r; } int n,k,rev[N],v,c,le,w[N]; ll b[N]; vector<int>a; void deb(pl x){ for(int i:x)cout<<i<<' '; puts(""); } void init(int n){ v=1; le=0; while(v<n)le++,v*=2; for(signed i=0;i<v;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(le-1)); int g=qp(3,(mo-1)/v); w[v/2]=1; for(int i=v/2+1;i<v;i++) w[i]=1ull*w[i-1]*g%mo; for(signed i=v/2-1;~i;i--) w[i]=w[i*2]; } void fft(int v,pl &a,int t){ static unsigned long long b[N]; int s=le-__builtin_ctz(v); for(int i=0;i<v;i++) b[rev[i]>>s]=a[i]; int c=0; w[0]=1; for(signed i=1;i<v;i*=2,c++) for(signed r=i*2,j=0;j<v;j+=r) for(signed k=0;k<i;k++){ int tx=b[j+i+k]*w[k+i]%mo; b[j+i+k]=b[j+k]+mo-tx; b[j+k]+=tx; } for(int i=0;i<v;i++) a[i]=b[i]%mo; if(t==0)return; int iv=qp(v,mo-2); for(signed i=0;i<v;i++) a[i]=1ull*a[i]*iv%mo; a.resize(v); reverse(a.begin()+1,a.end()); } pl operator *(pl x,pl y){ int s=x.size()+y.size()-1; init(s); x.resize(v); y.resize(v); //deb(x); //deb(y); fft(v,x,1); fft(v,y,1); for(int i=0;i<v;i++) x[i]=x[i]*y[i]%mo; fft(v,x,0); //deb(x); x.resize(s); return x; } void inv(int n,pl &b,pl &a){ if(n==1){ b[0]=qp(a[0],mo-2); return; } inv((n+1)/2,b,a); static pl c; init(n*2); c.resize(v); b.resize(v); for(int i=0;i<n;i++) c[i]=a[i]; fft(v,c,0); //deb(c); fft(v,b,0); //deb(b); for(int i=0;i<v;i++) b[i]=1ll*(2ll-1ll*c[i]*b[i]%mo+mo)%mo*b[i]%mo; //deb(b); fft(v,b,1); //deb(b); b.resize(n); //deb(b); } void ad(pl &x,pl y,int l){ x.resize(max((int)x.size(),(int)y.size()+l)); for(int i=0;i<y.size();i++) x[i+l]=(x[i+l]+y[i])%mo; } pl operator +(pl x,pl y){ ad(x,y,0); return x; } pl iv(pl x){ pl y; int n=x.size(); y.resize(n); inv(n,y,x); y.resize(n); return y; } pl operator /(pl a,pl y){ int n=a.size()-1,m=y.size()-1; pl x,b,t; x.resize(n+1); b.resize(m+1); for(int i=0;i<=n;i++) x[n-i]=a[i]; for(int i=0;i<=m;i++) b[m-i]=y[i]; for(int i=n-m+2;i<=m;i++) b[i]=0; b.resize(n-m+1); t=iv(b); x=x*t; x.resize(n-m+1); reverse(x.begin(),x.end()); return a; } pl operator -(pl x,pl y){ int s=max(x.size(),y.size()); x.resize(s); y.resize(s); for(int i=0;i<s;i++) x[i]=(x[i]-y[i]+mo)%mo; return x; } pl operator %(pl x,pl y){ int n=x.size()-1,m=y.size()-1; if(n<m)return x; if(!m){ pl a; a.resize(1); return a; } x=x-(x/y)*y; x.resize(m); return x; } int main(){ }
来源:https://www.cnblogs.com/cszmc2004/p/12444741.html