rt,多点求值第一个点跑了 19s。
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define N 300006
using namespace std;
inline int read()
{
int ret=0,f=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+(ch^48),ch=getchar();
return ret*f;
}
inline void write(int k)
{
if(k<0)putchar('-'),k=-k;
int nnum[20],ttp=0;
while(k)nnum[++ttp]=k%10,k/=10;
if(!ttp)nnum[++ttp]=0;
while(ttp)putchar(nnum[ttp--]^48);
}
namespace POLY{
const int MOD=998244353,G=3,invg=(MOD+1)/3;
int r[N];
inline int qpow(int x,int y)
{
if(y==0)return 1;
if(y==1)return x%MOD;
int ret=qpow(x,y>>1);
return ret*ret%MOD*qpow(x,y&1)%MOD;
}
inline void NTT(int len,int *a,int opt)
{
for(int i=0;i<len;i++)if(i<r[i])
swap(a[i],a[r[i]]);
for(int i=1;i<len;i<<=1)
{
int tmp=i<<1,Wn=qpow(opt==1?G:invg,(MOD-1)/tmp);
for(int j=0;j<len;j+=tmp)
{
int w=1,x,y;
for(int k=0;k<i;k++,w=w*Wn%MOD)
x=a[j+k],y=w*a[i+j+k]%MOD,a[j+k]=(x+y)%MOD,a[i+j+k]=(x+MOD-y)%MOD;
}
}
if(opt!=1)
{
int invn=qpow(len,MOD-2);
for(int i=0;i<len;i++)a[i]=a[i]*invn%MOD;
}
}
inline void times(int n,int m,int *a,int *b,int *ans)
{
int len=1,lg=0;
while(len<=n+m)len<<=1,lg++;
for(int i=0;i<len;i++)
r[i]=(r[i>>1]>>1)|((i&1)<<lg-1);
NTT(len,a,1),NTT(len,b,1);
for(int i=0;i<=len;i++)a[i]=a[i]*b[i]%MOD;
NTT(len,a,-1);
for(int i=0;i<=n+m;i++)ans[i]=a[i];
}
int c[N];
inline void getinv(int n,int *a,int *b)
{
if(n==1)return b[0]=qpow(a[0],MOD-2),(void)0;
getinv(n+1>>1,a,b);
int len=1,lg=0;
while(len<(n<<1))len<<=1,lg++;
for(int i=0;i<len;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(lg-1));
for(int i=0;i<n;i++)c[i]=a[i];
for(int i=n;i<len;i++)c[i]=0;
NTT(len,c,1),NTT(len,b,1);
for(int i=0;i<len;i++)
b[i]=(2+MOD-c[i]*b[i]%MOD)%MOD*b[i]%MOD;
NTT(len,b,-1);
for(int i=n;i<len;i++)b[i]=0;
memset(c,0,sizeof(c));
}
int f[N],g[N],fr[N],gr[N],invgr[N],dr[N],td[N],tmp[N];
inline void modulo(int n,int m,int *tf,int *tg,int *r)
{
for(int i=0;i<n+m<<1;i++)
f[i]=g[i]=fr[i]=gr[i]=invgr[i]=dr[i]=tmp[i]=td[i]=0;
for(int i=0;i<n;i++)f[i]=tf[i];
for(int i=0;i<m;i++)g[i]=tg[i];
for(int i=0;i<n;i++)fr[n-i-1]=f[i];
for(int i=0;i<m;i++)gr[m-i-1]=g[i];
getinv(n-m+1,gr,invgr),times(n,n-m+1,fr,invgr,dr);
for(int i=n-m;~i;i--)td[n-m-i]=dr[i];
times(m,n-m+1,g,td,tmp);
for(int i=0;i<m-1;i++)
r[i]=(f[i]+MOD-tmp[i])%MOD;
}
int *p[N<<2],length[N<<2],ta[N],tb[N];
void init(int len,int lg){for(int i=0;i<len;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(lg-1));}
void getp(int u,int l,int r,int *a)
{
length[u]=r-l+1,p[u]=new int[length[u]+1];
if(l==r)
return p[u][0]=(MOD-a[l]),p[u][1]=1,(void)0;
int mid=l+r>>1;
getp(u<<1,l,mid,a),getp(u<<1|1,mid+1,r,a);
int len=1,lg=0;
while(len<(length[u]+1<<1))len<<=1,lg++;
init(len,lg);
for(int i=0;i<=length[u<<1];i++)ta[i]=p[u<<1][i];
for(int i=length[u<<1]+1;i<len;i++)ta[i]=0;
for(int i=0;i<=length[u<<1|1];i++)tb[i]=p[u<<1|1][i];
for(int i=length[u<<1|1]+1;i<len;i++)tb[i]=0;
NTT(len,ta,1),NTT(len,tb,1);
for(int i=0;i<len;i++)ta[i]=ta[i]*tb[i]%MOD;
NTT(len,ta,-1);
for(int i=0;i<=length[u];i++)p[u][i]=ta[i];
}
void solve(int u,int l,int r,int *a,int *f,int *ans)
{
if(l==r)return ans[l]=*f,(void)0;
int mid=l+r>>1,md[length[u]+2]={0};
modulo(length[u],length[u<<1]+1,f,p[u<<1],md);
solve(u<<1,l,mid,a,md,ans);
modulo(length[u],length[u<<1|1]+1,f,p[u<<1|1],md);
solve(u<<1|1,mid+1,r,a,md,ans);
}
void evaluation(int n,int m,int *a,int *f,int *ans)
{
getp(1,1,m,a);
if(n>m)modulo(n,m+1,f,p[1],f);
solve(1,1,m,a,f,ans);
}
}
int n,m,a[N],f[N],ans[N];
main()
{
n=read()+1,m=read();
for(int i=0;i<n;i++)f[i]=read();
for(int i=1;i<=m;i++)a[i]=read();
POLY::evaluation(n,m,a,f,ans);
for(int i=1;i<=m;i++)write(ans[i]),putchar(10);
return 0;
}