// #include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
using ll=long long;
const int N=500005,inf=0x3fffffff;
const long long INF=0x3f3f3f3f3f3f,mod=998244353,inv2=499122177,inv3=332748118;
int getlen(int k)
{
int ret=0;
while(k){ret++;k>>=1;}
return ret;
}
int getrev(int k,int len)
{
int ret=0;
while(k){ret=(ret<<1|(k&1));k>>=1;len--;}
return ret<<len;
}
ll qpow(ll a,ll b)
{
ll ret=1,base=a;
while(b)
{
if(b&1) ret=ret*base%mod;
base=base*base%mod;
b>>=1;
}
return ret;
}
ll inv(ll k){return qpow(k,mod-2);}
int pos[N];
void ntt(ll *a,int limit,int op)
{
for(int i=0;i<limit;i++)
if(i<pos[i]) swap(a[i],a[pos[i]]);
for(int len=2;len<=limit;len<<=1)
{
ll base=qpow(op==1?3:inv3,(mod-1)/len);
for(int l=0;l<limit;l+=len)
{
ll now=1;
for(int i=l;i<l+len/2;i++)
{
ll x=a[i]%mod,y=now*a[i+len/2]%mod;
a[i]=(x+y)%mod;
a[i+len/2]=(x-y+mod)%mod;
now=now*base%mod;
}
}
}
}
ll a[N],b[N],c[N];
inline void multi2(ll *f,ll *invt,int n,int m,int llen)//f*=g
{
int limit=1;
while(limit<=n+2*m) limit<<=1;
int len=getlen(limit-1);
for(int i=0;i<limit;i++)
{
pos[i]=getrev(i,len);
a[i]=f[i]; b[i]=invt[i];
}
ntt(a,limit,1); ntt(b,limit,1);
for(int i=0;i<limit;i++) a[i]=b[i]*((2-a[i]*b[i]%mod)%mod+mod)%mod;
ntt(a,limit,-1);
ll tmp=inv(limit);
for(int i=0;i<llen;i++) invt[i]=a[i]*tmp%mod;
for(int i=llen;i<limit;i++) invt[i]=0;
}
void multi1(ll *f,ll *t,ll *invt,int n,int m,int llen)//开根
{
int limit=1;
while(limit<=n+m) limit<<=1;
int len=getlen(limit-1);
for(int i=0;i<limit;i++)
{
pos[i]=getrev(i,len);
a[i]=f[i]; b[i]=t[i]; c[i]=invt[i];
}
ntt(a,limit,1); ntt(b,limit,1); ntt(c,limit,1);
for(int i=0;i<limit;i++) a[i]=(b[i]+a[i]*c[i]%mod)%mod*inv2%mod;
ntt(a,limit,-1);
ll tmp=inv(limit);
for(int i=0;i<llen;i++) t[i]=a[i]*tmp%mod;
for(int i=llen;i<limit;i++) t[i]=0;
}
int n,tmp1[N],tmp2[N],pp1,pp2;
ll f[N],t[N],invt[N];
void solve2(int len)
{
pp2=0;
while(len>1)
{
tmp2[++pp2]=len;
len=len+1>>1;
}
invt[0]=inv(t[0]);
while(pp2) multi2(t,invt,n,tmp2[pp2]+1>>1,tmp2[pp2]),pp2--;
}
void solve1(int len)//开根
{
while(len>1)
{
tmp1[++pp1]=len;
len=len+1>>1;
}
t[0]=1;
while(pp1)
{
for(int i=0;i<(tmp1[pp1]+1>>1);i++) invt[i]=0;
solve2(tmp1[pp1]+1>>1);
multi1(f,t,invt,n,tmp1[pp1]+1>>1,tmp1[pp1]);
pp1--;
}
}
int main()
{
// freopen("in.txt","r",stdin);
cin>>n;
for(int i=0;i<n;i++) scanf("%lld",&f[i]);
solve1(n<<1);
for(int i=0;i<n;i++) printf("%lld ",t[i]);
return 0;
}
一直过不了,如果每次求得了当前的B(x),再去求B(x)的逆元的话复杂度不应该是O(nlog^{2}n)的吗?题解似乎也是这么做的,但为什么题解说的复杂度是O(nlogn)的呢?我一直tle#8之后的样例
请问一下是时间复杂度的问题还是我的常数过大了,并且还有一个问题,如果一开始给的参数是n的话会存在半边答案不正确,给了n<<1才是正确答案,请问一下为什么是n<<1而不是n