社区讨论

刚学OI,松不过怎么办?

P5273【模板】多项式幂函数(加强版)参与者 8已保存回复 9

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
9 条
当前快照
1 份
快照标识符
@mi7wzx48
此快照首次捕获于
2025/11/21 04:59
4 个月前
此快照最后确认于
2025/11/21 04:59
4 个月前
查看原帖
众所周知,多项式快速幂是O(nlogn)O(n\log n)的,并且数据规模是n105n\le 10^5
但是!我超大的常数搞得T掉了
怎么办?
CPP
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define fr(i,a,b) for(long long i=(a),_end_=(b);i<=_end_;i++)
#define fd(i,a,b) for(long long i=(a),_end_=(b);i>=_end_;i--)
long long read()
{
	long long r=0,t=1,c=getchar();
	while(c<'0'||c>'9')
	{
		t=c=='-'?-1:1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		r=(r<<3)+(r<<1)+(c^48);
		c=getchar();
	}
	return r*t;
}
long long readmod(long long p)
{
	long long r=0,t=1,c=getchar();
	while(c<'0'||c>'9')
	{
		t=c=='-'?-1:1;
		c=getchar();
	}
	while(c>='0'&&c<='9')
	{
		r=(r*10+c-48)%p;
		c=getchar();
	}
	return (r*t+p)%p;
}
#define N (1<<18)+10
#include<stdlib.h>
namespace ntt
{
	const long long mod=998244353,g=3,gi=332748118;
	long long l,p[N];
	long long _a[N],_b[N],_c[N];
	long long power(long long a,long long b,long long m)
	{
		long long r=1;
		a%=m;
		while(b)
		{
			if(b&1)
				r=r*a%m;
			a=a*a%m;
			b>>=1;
		}
		return r;
	}
	long long inv(long long a)
	{
		return power(a,mod-2,mod);
	}
	void init(long long n)
	{
		if((1<<l)>=n&&(1<<(l-1))<n)
			return;
		l=0;
		while((1<<l)<n)
			l++;
		fr(i,0,(1<<l)-1)
			p[i]=(p[i>>1]>>1)|((i&1)<<(l-1));
	}
	void NTT(long long *a,long long opt)
	{
		fr(i,0,(1<<l)-1)
			if(i<p[i])
				swap(a[i],a[p[i]]);
		fr(i,0,l-1)
		{
			long long wn=power(opt==1?g:gi,(mod-1)/(1<<(i+1)),mod);
			for(long long j=0;j<(1<<l);j+=(1<<(i+1)))
			{
				long long w=1;
				fr(k,0,(1<<i)-1)
				{
					long long x=a[j+k],y=w*a[j+k+(1<<i)]%mod;
					a[j+k]=(x+y)%mod;
					a[j+k+(1<<i)]=(x-y+mod)%mod;
					w=w*wn%mod;
				}
			}
		}
		if(opt==-1)
		{
			long long i=inv(1<<l);
			fr(j,0,(1<<l)-1)
				a[j]=a[j]*i%mod;
		}
	}
	void mul(long long *c,long long *a,long long *b,long long n,long long m)
	{
		init(n+m+1);
		fr(i,0,(1<<l)-1)
			_a[i]=_b[i]=0;
		fr(i,0,n)
			_a[i]=a[i];
		fr(i,0,m)
			_b[i]=b[i];
		NTT(_a,1);
		NTT(_b,1);
		fr(i,0,(1<<l)-1)
			_c[i]=_a[i]*_b[i]%mod;
		NTT(_c,-1);
		fr(i,0,n+m)
			c[i]=_c[i];
	}
	long long _d[N];
	void inv(long long *c,long long *a,long long p)
	{
		if(p==1)
		{
			c[0]=inv(a[0]);
			return;
		}
		inv(c,a,(p+1)/2);
		mul(_d,a,c,p-1,p-1);
		fr(i,p,p+p-2)
			_d[i]=0;
		fr(i,1,p-1)
			_d[i]=mod-_d[i];
		_d[0]=(2+mod-_d[0])%mod;
		mul(c,_d,c,p-1,p-1);
		fr(i,p,p+p-2)
			c[i]=0;
	}
	void d(long long *c,long long *a,long long l)
	{
		fr(i,0,l-2)
			c[i]=a[i+1]*(i+1)%mod;
		c[l-1]=0;
	}
	void integral(long long *c,long long *a,long long l)
	{
		fr(i,1,l-1)
			c[i]=a[i-1]*inv(i)%mod;
		c[0]=0;
	}
	long long _f[N];
	void ln(long long *c,long long *a,long long l)
	{
		d(_f,a,l);
		inv(c,a,l);
		mul(_f,_f,c,l-1,l-1);
		fr(i,l,l+l-2)
			_f[i]=0;
		integral(c,_f,l);
	}
	long long _g[N];
	void exp(long long *c,long long *a,long long l)
	{
		if(l==1)
		{
			if(a[0]!=0)
				exit(-1);
			c[0]=1;
			return;
		}
		exp(c,a,(l+1)/2);
		ln(_g,c,l);
		fr(i,0,l-1)
			_g[i]=a[i]-_g[i];
		_g[0]++;
		mul(c,c,_g,l-1,l-1);
	}
	long long _h[N],_i[N];
	void power(long long *c,long long *a,long long n,long long k)
	{
		if(!*a)
		{
			long long i=0;
			while(!a[i]&&i<n)
				i++;
			if(i==n||i*k>=n)
			{
				fr(j,0,n-1)
					c[j]=0;
				return;
			}
			power(_i,a+i,n-i,k);
			fr(j,k*i,n-1)
				c[j]=_i[j-k*i];
			fr(j,0,k*i-1)
				c[j]=0;
			return;
		}
		long long aa=*a,ai=inv(*a),ap=power(*a,k,mod);
		fr(i,0,n-1)
			a[i]=a[i]*ai%mod;
		ln(_h,a,n);
		fr(i,0,n-1)
			_h[i]=_h[i]*k%mod;
		exp(c,_h,n);
		fr(i,0,n-1)
		{
			a[i]=a[i]*aa%mod;
			c[i]=c[i]*ap%mod;
		}
	}
}
long long n,k,a[N],c[N];
int main()
{
	n=read();
	k=readmod(ntt::mod);
	fr(i,0,n-1)
		a[i]=read();
	ntt::power(c,a,n,k);
	fr(i,0,n-1)
		printf("%lld%c",c[i],i==n?'\n':' ');
	return 0;
}

回复

9 条回复,欢迎继续交流。

正在加载回复...