我的多项式求逆跑出来要 2s 多,比别人慢好几倍,有没有佬看看什么地方能优化。
#include<bits/stdc++.h>
#define ld long double
#define ui unsigned int
#define ull unsigned long long
#define int long long
#define eb emplace_back
#define pb pop_back
#define ins insert
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define power(x) ((x)*(x))
#define gcd(x,y) (__gcd((x),(y)))
#define lcm(x,y) ((x)*(y)/gcd((x),(y)))
#define lg(x,y) (__lg((x),(y)))
using namespace std;
namespace FastIO
{
template<typename T=int> inline T read()
{
T s=0,w=1; char c=getchar();
while(!isdigit(c)) {if(c=='-') w=-1; c=getchar();}
while(isdigit(c)) s=(s<<1)+(s<<3)+(c^48),c=getchar();
return s*w;
}
template<typename T> inline void read(T &s)
{
s=0; int w=1; char c=getchar();
while(!isdigit(c)) {if(c=='-') w=-1; c=getchar();}
while(isdigit(c)) s=(s<<1)+(s<<3)+(c^48),c=getchar();
s=s*w;
}
template<typename T,typename... Args> inline void read(T &x,Args &...args)
{
read(x),read(args...);
}
template<typename T> inline void write(T x,char ch)
{
if(x<0) x=-x,putchar('-');
static char stk[25]; int top=0;
do {stk[top++]=x%10+'0',x/=10;} while(x);
while(top) putchar(stk[--top]);
putchar(ch);
return;
}
}
using namespace FastIO;
namespace MTool
{
template<typename T> inline void Swp(T &a,T &b) {T t=a;a=b;b=t;}
template<typename T> inline void cmax(T &a,T b) {a=a>b?a:b;}
template<typename T> inline void cmin(T &a,T b) {a=a<b?a:b;}
struct ModTool
{
#define TA template<typename T,typename... Args>
#define TT template<typename T>
int Mod;
ModTool(int MOD=998244353):Mod(MOD){}
void ChangeMod(int MOD) {Mod=MOD;}
TT inline void Madd(T &a,T b) {a=a+b>Mod?a+b-Mod:a+b;}
TT inline void Mdel(T &a,T b) {a=a-b<0?a-b+Mod:a-b;}
TT inline void Mmul(T &a,T b) {a=a*b%Mod;}
TT inline void Mmod(T a) {a=(a%Mod+Mod)%Mod;}
TT inline T Cadd(T a,T b) {return a+b>=Mod?a+b-Mod:a+b;}
TT inline T Cdel(T a,T b) {return a-b<0?a-b+Mod:a-b;}
TT inline T Cmul(T a,T b) {return a*b%Mod;}
TT inline T Cmod(T a) {return (a%Mod+Mod)%Mod;}
TA inline void Madd(T &a,T b,Args... args) {Madd(a,Cadd(b,args...));}
TA inline void Mdel(T &a,T b,Args... args) {Mdel(a,Cadd(b,args...));}
TA inline void Mmul(T &a,T b,Args... args) {Mmul(a,Cmul(b,args...));}
TA inline T Cadd(T a,T b,Args... args) {return Cadd(Cadd(a,b),args...);}
TA inline T Cdel(T a,T b,Args... args) {return Cdel(Cdel(a,b),args...);}
TA inline T Cmul(T a,T b,Args... args) {return Cmul(Cmul(a,b),args...);}
TT inline T qpow(T a,T b) {int res=1; while(b) {if(b&1) Mmul(res,a); Mmul(a,a); b>>=1;} return res;}
TT inline T qmul(T a,T b) {int res=0; while(b) {if(b&1) Madd(res,a); Madd(a,a); b>>=1;} return res;}
TT inline T spow(T a,T b) {int res=1; while(b) {if(b&1) res=qmul(res,a); a=qmul(a,a); b>>=1;} return res;}
private:TT inline void exgcd(T A,T B,T &X,T &Y) {if(!B) return X=1,Y=0,void(); exgcd(B,A%B,Y,X),Y-=X*(A/B);}
public:TT inline T Ginv(T x) {T A=0,B=0; exgcd(x,Mod,A,B); return Cmod(A);}
#undef TT
#undef TA
};
}
using namespace MTool;
inline void file()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
return;
}
bool Mbe;
namespace Poly
{
static const int MAX=1000010;
static const double PI=acos(-1.0);
struct Complex
{
double x,y;
Complex(double X=0,double Y=0):x(X),y(Y) {}
inline friend Complex operator + (Complex a,Complex b) {return Complex(a.x+b.x,a.y+b.y);}
inline friend Complex operator - (Complex a,Complex b) {return Complex(a.x-b.x,a.y-b.y);}
inline friend Complex operator * (Complex a,Complex b) {return Complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
template<typename T> inline friend Complex operator / (Complex a,T b) {return Complex(a.x/b,a.y/b);}
};
int n,m,f[MAX],g[MAX];
int rev[MAX],nowrev;
template<typename T> inline void ReArrange(T *F,int N)
{
if(nowrev!=N)
{
rev[0]=0,nowrev=N;
for(int i=1;i<N;++i) rev[i]=(rev[i>>1]>>1)|((i&1)*N>>1);
}
for(int i=0;i<N;++i) if(rev[i]>i) Swp(F[i],F[rev[i]]);
}
static const int gn=332748118,gni=3;
ModTool Nmod;
int H[MAX];
inline void NTT(int *F,int N,int typ)
{
ReArrange(F,N);
for(int len=2,l=1;len<=N;len<<=1,l<<=1)
{
int stp=Nmod.qpow(typ==1?gn:gni,(Nmod.Mod-1)/len);
for(int st=0;st<N;st+=len)
{
int omega=1,U,V;
for(int i=0;i<l;++i)
U=F[st+i],V=Nmod.Cmul(omega,F[st+i+l]),
F[st+i]=Nmod.Cadd(U,V),F[st+i+l]=Nmod.Cdel(U,V),
Nmod.Mmul(omega,stp);
}
}
if(typ==-1)
{
int Ninv=Nmod.Ginv(N);
for(int i=0;i<N;++i) Nmod.Mmul(F[i],Ninv);
}
}
void InvF(int *F,int *G,int N)
{
int K=1; while(K<=N) K<<=1; N=K;
memset(H,0,sizeof H);
G[0]=Nmod.Ginv(F[0]);
for(int len=2;len<=N;len<<=1)
{
int M=len<<1;
memcpy(H,F,sizeof(int)*len);
memset(H+len,0,sizeof(int)*len);
NTT(H,M,1),NTT(G,M,1);
for(int i=0;i<M;++i) Nmod.Mmul(G[i],Nmod.Cdel(2ll,Nmod.Cmul(G[i],H[i])));
NTT(G,M,-1);
memset(G+len,0,sizeof(int)*len);
}
}
}
namespace LgxTpre
{
static const int MAX=1000010;
static const int inf=2147483647;
static const int INF=4557430888798830399;
static const int mod=1e9+7;
static const int bas=131;
int F[MAX],G[MAX];
inline void mian()
{
using Poly::n; read(n);
for(int i=0;i<n;++i) read(F[i]);
Poly::InvF(F,G,n);
for(int i=0;i<n;++i) write(G[i],' ');
puts("");
return;
}
}
bool Med;
signed main()
{
file();
fprintf(stderr,"%.3lf MB\n",abs(&Med-&Mbe)/1048576.0);
int Tbe=clock();
LgxTpre::mian();
int Ted=clock();
cerr<<1e3*(Ted-Tbe)/CLOCKS_PER_SEC<<" ms\n";
return (0-0);
}