萌新求助poly
  • 板块学术版
  • 楼主LgxTpre
  • 当前回复13
  • 已保存回复13
  • 发布时间2023/6/6 20:11
  • 上次更新2023/10/23 13:48:45
查看原帖
萌新求助poly
66709
LgxTpre楼主2023/6/6 20:11

我的多项式求逆跑出来要 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);
}
2023/6/6 20:11
加载中...