WA55分求助
查看原帖
WA55分求助
128433
C6H14楼主2021/12/28 13:43

翻了20页提交记录,就我一个55分

const ll maxn=998244353,SIZE=100005;
inline ll qpow (ll a,ll b)
{
	ll ans=1;
	while (b)
	{
		if (b&1) ans=ans*a%maxn;
		a=a*a%maxn;
		b>>=1;
	}
	return ans;
}
void exgcd(ll a,ll b,ll &x,ll &y)
{
	if (b==0)
	{
		x=1,y=0;
		return;
	}
	exgcd(b,a%b,y,x);
	y-=(a/b)*x;
}
inline ll rev(ll x)
{
	ll ans,tmp;
	exgcd(x,maxn,ans,tmp);
	return (ans%maxn+maxn)%maxn;
}
int n,m,rn,tr[SIZE<<2];
ll f[SIZE<<2],g[SIZE<<2];
const ll G=3,RG=rev(G);
inline void times(ll *f,ll *g,ll n)
{
	for (int i=0;i<n;++i)
		f[i]=f[i]*g[i]%maxn;
}
inline void trans(ll n)
{
	static ll size=0;
	if (size==n)
		return;
	size=n;
	for (int i=0;i<n;++i)
		tr[i]=(tr[i>>1]>>1)|((i&1)?n>>1:0);
}
inline void ntt(ll *g,ll n,bool op)
{
	trans(n);
	static ll f[SIZE<<2],w[SIZE<<2]={1};
	for (int i=0;i<n;++i)
		f[i]=((maxn<<5ll)+g[tr[i]])%maxn;
	for (int l=1;l<n;l<<=1)
	{
		ll tG=qpow(op?G:RG,(maxn-1)/(l+l));
		for (int i=1;i<l;++i)
			w[i]=w[i-1]*tG%maxn;
		for (int k=0;k<n;k+=l+l)
			for (int p=0;p<l;++p)
			{
			    ll tt=w[p]*f[k|l|p]%maxn;
			    f[k|l|p]=f[k|p]+maxn-tt;
			    f[k|p]+=tt;
			}      
		if (l==(1<<10))
			for (int i=0;i<n;++i)
				f[i]%=maxn;
	}
	if (!op)
	{
		ll invn=rev(n);
		for (int i=0;i<n;++i)
			g[i]=f[i]%maxn*invn%maxn;
	}
	else
		for (int i=0;i<n;++i)
			g[i]=f[i]%maxn;
}
inline void mult(ll *f,ll *g,ll n,ll m)
{
	static ll s[SIZE<<2];
	memcpy(s,g,sizeof(ll)*m);
	m+=n,n=1;
	while (n<m)
		n<<=1;
	ntt(f,n,1),ntt(s,n,1);
	for (int i=0;i<n;++i)
		f[i]=f[i]*s[i]%maxn;
	ntt(f,n,0);
}
inline void _mult(ll *f,ll *g,ll len,ll lim)
{
	static ll s[SIZE<<2];
	int n=1;
	while (n<len)
		n<<=1;
	n<<=1;
	memset(s,0,sizeof(ll)*n);
	memcpy(s,g,sizeof(ll)*n);
	ntt(f,n,1),ntt(s,n,1);
	for (int i=0;i<n;++i)
		f[i]=f[i]*s[i]%maxn;
	ntt(f,n,0);
	memset(f+lim,0,sizeof(ll)*(n-lim));
	memset(s,0,sizeof(ll)*n);
}
inline void print(ll *f,ll len)
{
	for (int i=0;i<len;++i)
		write(f[i],' ');
}
inline void inv(ll *f,ll m)
{
	int n=1;
	while (n<m)
		n<<=1;
	static ll w[SIZE<<2],r[SIZE<<2],sav[SIZE<<2];
	w[0]=rev(f[0]);
	for (int len=2;len<=n;len<<=1)
	{
		for (int i=0;i<(len>>1);++i)
			r[i]=(w[i]<<1)%maxn;
		memcpy(sav,f,sizeof(ll)*len);
		ntt(w,len<<1,1),times(w,w,len<<1);
		ntt(sav,len<<1,1),times(w,sav,len<<1);
		ntt(w,len<<1,0),memset(w+len,0,sizeof(ll)*len);
		for (int i=0;i<len;++i)
			w[i]=(r[i]-w[i]+maxn)%maxn;
	}
	memcpy(f,w,sizeof(ll)*m);
	memset(sav,0,sizeof(ll)*2*n);
	memset(w,0,sizeof(ll)*2*n);
	memset(r,0,sizeof(ll)*2*n);
}
inline void sqrt(ll *f,ll m)
{
	ll n=1;
	while (n<m) n<<=1;
	static ll b[SIZE<<2],c[SIZE<<2];
	b[0]=1;
	for (int len=2;len<=n;len<<=1)
	{
		for (int i=0;i<(len>>1);++i)
			c[i]=(b[i]<<1)%maxn;
		inv(c,len);
		ntt(b,len,1), 
		times(b,b,len),
		ntt(b,len,0);
		for (int i=0;i<len;++i)
			b[i]=(f[i]+b[i])%maxn;
		_mult(b,c,len,len);
	}
	memcpy(f,b,sizeof(ll)*m);
	memset(b,0,sizeof(ll)*2*n);
	memset(c,0,sizeof(ll)*2*n);
}
int main ()
{
	n=read();
	for (int i=0;i<n;++i)
		f[i]=read();
	sqrt(f,n);
	print(f,n);
	return 0;
}
2021/12/28 13:43
加载中...