优化了一下板子,现在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