【LuoguP5850】calc加强版
【LuoguP5850】calc加强版
by AmanoKumiko
Description
对于\(n=1,2,3 ... m\),求出所有合法序列的权值
其中,合法的定义为每个元素都为\([1,k]\)中的整数,同时每个元素都不相同
同时,权值为所有元素的乘积
两个序列不同当且仅当他们任意一位不一样。
对\(998244353\)取模
Input
一行两个数\(k,m\)
Output
共\(m\)行表示答案
Sample Input
13 8
Sample Output
91
7462
546546
35387352
3869654
396558319
363789591
879373476
Data Constraint
\(1\le m\le k\le998244353\)
Solution
不难发现对于一个\(n\),要求的就是\(n![x^n]\prod_{i=1}^k(ix+1)\)
由于\(k\)很大,所以不能分治\(NTT\)
但是可以运用积化和的\(trick\)
令\(F(x)=\prod_{i=1}^k(ix+1)\)
那么\(ln\ F(x)=\sum_{i=1}^kln(ix+1)\)
根据\(-ln(1-x)=\sum \frac{x^i}{i}\)
原式变为\(\sum_{i=1}^kln(1-(-ix))=\sum_{i=1}^k-\sum_{j=1}^{+∞}\frac{(-ix)^j}{j}\)
即\(-\sum_{i=1}^{+∞}\frac{(-1)^ix^i}{i}\sum_{j=1}^kj^i\)
那么现在需要的就是快速预处理自然数幂和
考虑其\(EGF\)
即\(\sum_{i=1}^{k}\sum_{j=1}^{+∞}\frac{(ix)^j}{j!}=\sum_{i=1}^{k}e^{ix}=\frac{e^{(k+1)x}\ \ -e^x}{e^x-1}\)
由于分母常数项为\(0\),所以上下要同时除以\(x\)
Code
#include
using namespace std;
#define F(i,a,b) for(int i=a;i<=b;i++)
#define Fd(i,a,b) for(int i=a;i>=b;i--)
#define N 2000010
#define mo 998244353
vectorIs;
int rev[N],G1[N],G2[N],fac[N],ifac[N],inv[N];
int mod(int x){return x>=mo?x-mo:x;}
int mi(int x,int y){
if(y==1)return x;
return y%2?1ll*x*mi(1ll*x*x%mo,y/2)%mo:mi(1ll*x*x%mo,y/2);
}
void init(){
Is.push_back(1);
fac[0]=ifac[0]=1;
F(i,1,N-10)fac[i]=1ll*fac[i-1]*i%mo,inv[i]=(i==1?1:1ll*mo/i*mod(mo-1ll*inv[mo%i]%mo)%mo);
ifac[N-10]=mi(fac[N-10],mo-2);
Fd(i,N-11,1)ifac[i]=1ll*ifac[i+1]*(i+1)%mo;
for(int l=1;l<=N-10;l<<=1)G1[l]=mi(3,(mo-1)/(l*2)),G2[l]=mi(G1[l],mo-2);
}
void BRT(int x){F(i,0,x-1)rev[i]=(rev[i>>1]>>1)|((i&1)?(x>>1):0);}
struct poly{
vectorval;
void clear(){vector().swap(val);}
int sz(){return val.size();}
void rsz(int x){val.resize(x);}
void shrink(){for(;sz()&&!val.back();val.pop_back());}
poly modxn(int x){
if(val.size()<=x)return (poly){val};
else return (poly){vector(val.begin(),val.begin()+x)};
}
poly I(){return (poly){Is};}
int operator[](int x)const{
if(x<0||x>=val.size())return 0;
return val[x];
}
void NTT(int x){
F(i,0,sz()-1)if(rev[i]y.sz())swap(x,y);
poly ret;
ret.rsz(x.sz()+y.sz());
F(i,0,ret.sz()-1){
for(int j=0;j<=i&&j=sz()?0:val[i+1])*(i+1)%mo;
g=inver(Len);
g*=f;
g.modxn(Len);
Fd(i,Len-1,1)g.val[i]=1ll*g[i-1]*inv[i]%mo;
g.val[0]=0;
return g.modxn(Len);
}
poly Exp(int Len){
poly f;
f.clear();
f.val.push_back(1);
for(int i=2;i