首先 【模板】多项式指数函数(多项式 exp) 的时限为 2s。
而这题 1s,对于我与几位大常熟选手不太友好。
或者有谁帮我卡卡常或者证明时复假掉了。
代码。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define Pmod 998244353ll
#define Gmod 3ll
#define Gimod 332748118ll
const int y=((__int128)1<<64)/Pmod;
int n,m;
vector<int>a,b,c,d;
inline int PMOD(int a){
__int128 Q=((__int128)(a)*y)>>64;
return a-Q*Pmod;
}
inline int power(int x,int y){
if(y==0) return 1;
int tot=power(x,y>>1);
if(y&1) return PMOD(PMOD(tot*tot)*x);
else return PMOD(tot*tot);
}
void NTT(vector<int>&a,int val){
int n=a.size()-1,mid=(a.size()>>1)-1;
if(n==0) return;
vector<int>p,q;
for(int i=0;i<=mid;i++) p.push_back(0),q.push_back(0);
for(int i=0;i<=n;i+=2) p[i>>1]=a[i],q[i>>1]=a[i+1];
NTT(p,val),NTT(q,val);
int Wn=power(((val==1) ? Gmod : Gimod),(Pmod-1)/a.size()),w=1;
for(int i=0;i<=mid;i++,w=PMOD(w*Wn)){
int t=PMOD(w*q[i]);
a[i]=PMOD(p[i]+t),a[i+mid+1]=PMOD(p[i]-t+Pmod);
}
}
void INV(vector<int>a,vector<int>&b,int M){
if(M==1){
b.clear();
b.push_back(power(a[0],Pmod-2));
return;
}
INV(a,b,M+1>>1);
int len=1;while(len<M*2) len*=2;
len--;
while(a.size()<=len) a.push_back(0);
while(a.size()>len+1) a.pop_back();
while(b.size()<a.size()) b.push_back(0);
for(int i=M;i<=len;i++) a[i]=0;
NTT(a,1),NTT(b,1);
for(int i=0;i<=len;i++) b[i]=(2-a[i]*b[i]%Pmod+Pmod)%Pmod*b[i]%Pmod;
NTT(b,-1);
int inv=power(len+1,Pmod-2);
for(int i=0;i<=len;i++) b[i]=(b[i]*inv)%Pmod;
for(int i=M;i<=len;i++) b[i]=0;
}
inline void get_cut(vector<int>a,vector<int>&b){
b.clear();
for(int i=1;i<a.size();i++) b.push_back(i*a[i]%Pmod);
b.push_back(0);
}
inline void get_int(vector<int>a,vector<int>&b){
b.clear();
b.push_back(0);
for(int i=1;i<a.size();i++) b.push_back(a[i-1]*power(i,Pmod-2)%Pmod);
}
inline void getln(vector<int>&a,int n){
get_cut(a,b);
INV(a,c,n+1);
int len=1;while(len<=2*n) len*=2;
len--;
while(b.size()<=len) b.push_back(0);
while(b.size()>len+1) b.pop_back();
while(c.size()<=len) c.push_back(0);
while(c.size()>len+1) c.pop_back();
NTT(b,1),NTT(c,1);
for(int i=0;i<b.size();i++) b[i]=(b[i]*c[i])%Pmod;
NTT(b,-1);
int inv=power(len+1,Pmod-2);
for(int i=0;i<b.size();i++) b[i]=(b[i]*inv)%Pmod;
get_int(b,a);
}
void getexp(vector<int>a,vector<int>&b,int n){
if(n==1){
b.clear();
b.push_back(1);
return;
}
getexp(a,b,(n+1)>>1);
vector<int>p=b;
getln(p,n);
int len=1;while(len<=n*2) len*=2;
len--;
while(a.size()<=len) a.push_back(0);
while(a.size()>len+1) a.pop_back();
while(b.size()<=len) b.push_back(0);
while(b.size()>len+1) b.pop_back();
while(p.size()<=len) p.push_back(0);
while(p.size()>len+1) p.pop_back();
p[0]=(a[0]-p[0]+1+Pmod)%Pmod;
for(int i=1;i<=len;i++) p[i]=(a[i]-p[i]+Pmod)%Pmod;
for(int i=n;i<=len;i++) b[i]=p[i]=0;
NTT(b,1),NTT(p,1);
for(int i=0;i<=len;i++) b[i]=(b[i]*p[i])%Pmod;
NTT(b,-1);
int inv=power(len+1,Pmod-2);
for(int i=0;i<=len;i++) b[i]=(b[i]*inv)%Pmod;
for(int i=n;i<=len;i++) b[i]=p[i]=0;
}
int V[100010];
int buc[100010];
int Inv[100010];
signed main() {
// freopen("data.txt","r",stdin);
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>V[i],buc[V[i]]++;
for(int i=0;i<=m;i++) a.push_back(0),Inv[i]=power(i,Pmod-2);
for(int i=1;i<=m;i++) if(buc[i]) for(int j=1;i*j<=m;j++) a[i*j]=(a[i*j]+buc[i]*Inv[j]%Pmod)%Pmod;
getexp(a,d,m+1);
for(int i=1;i<=m;i++) cout<<d[i]<<"\n";
return 0;
}