题解 P5850【calc 加强版】
题意
对 $n\in[1,m]$ 求
$$\sum_{a_{1,\cdots n}\in[1,k],a_i\ne a_j(1\le i<j\le n)}\prod_{i=1}^n a_i$$
对 $998244353$ 取模。
$m\le 5\times 10^5$,$k<998244353$.
思路
考虑这个式子的意义,先不考虑数列的顺序,写出答案的 $\text{OGF }F(x)$。
不难发现
$$F(x)=\prod_{i=1}^k(1+ix)$$
这个先考虑 $\ln$ 后转成加法。
$$\begin{aligned}F(x)&=\exp\left(\sum_{i=1}^k\ln(1+ix)\right)\\\end{aligned}$$
我们知道:
$$\ln(1-x)=-\sum_{i=1}^{n}\frac{x^i}i$$
$$\begin{aligned}F(x)&=\exp\left(\sum_{i=1}^k\ln(1+ix)\right)\\&=\exp\left(-\sum_{i=1}^k\sum_{j=1}^n\frac{(-ix)^j}j\right)\\&=\exp\left(\sum_{j=1}^n\frac{(-1)^{j+1}}{j}x^j\sum_{i=1}^ki^j\right)\end{aligned}$$ 现在要求 $j\in[1,n]$ 的自然数幂和。令它的 $\text{EGF}$ 为 $G(x)$:
$$\begin{aligned}G(x)&=\sum_{i=0}^n\dfrac{x^i}{i!}\sum_{j=1}^kj^i\\&=\sum_{j=1}^k\sum_{i=0}^n\dfrac{(jx)^i}{i!}\\&=\sum_{j=1}^ke^{jx}\\&=\dfrac{e^{x(k+1)}-e^x}{e^x-1}\end{aligned}$$
分子分母常数都是 $0$,同除 $x$ 就好了。
注意 $\text{EGF}$ 乘上 $i!$。
注意答案乘上 $n!$。
时间复杂度 $\Theta(n\log n)$。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
namespace IO{//by cyffff
}
const int N=1048576+10,mod=998244353,inv2=mod+1>>1;
namespace Init{
int fac[N],ifac[N],inv[N],G[21][N];
inline int qpow(int x,int y){
int res=1;
while(y){
if(y&1) res=1ll*res*x%mod;
x=1ll*x*x%mod;
y>>=1;
}
return res;
}
inline void getG(){
for(int i=0;i<21;i++){
int *P=G[i],W=1<<i;
P[0]=1;
P[1]=qpow(3,(mod-1)/(1<<i+1));
const int tmp=P[1];
for(int j=2;j<W;j++)
P[j]=1ll*P[j-1]*tmp%mod;
}
}
inline void Prefix(int L){
fac[0]=1;
for(int i=1;i<=L;i++)
fac[i]=1ll*fac[i-1]*i%mod;
ifac[L]=qpow(fac[L],mod-2);
for(int i=L;i>=1;i--)
ifac[i-1]=1ll*ifac[i]*i%mod;
for(int i=1;i<=L;i++)
inv[i]=1ll*ifac[i]*fac[i-1]%mod;
}
}
using namespace Init;
namespace Poly{
int lim,rev[N];
int F[N],G[N],H[N];
int T1[N],T2[N],T3[N];
inline void init(int n,int mode=1){
if(mode){
int l=0;
for(lim=1;lim<=n;lim<<=1)l++;
for(int i=1;i<lim;i++)
rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
}else{
for(lim=1;lim<=n;lim<<=1);
}
}
inline void NTT(int *a,int T){
for(int i=0;i<lim;i++)
if(i<rev[i])
swap(a[i],a[rev[i]]);
for(int i=1,o=0;i<lim;i<<=1,o++){
const int *P=::G[o];
for(int j=0;j<lim;j+=(i<<1)){
int t1,t2;
for(int k=0;k<i;k++){
t1=a[j+k];
t2=1ll*P[k]*a[i+j+k]%mod;
a[j+k]=(t1+t2)%mod;
a[i+j+k]=(t1-t2+mod)%mod;
}
}
}
if(T==1) return ;
int Inv=qpow(lim,mod-2);
reverse(a+1,a+lim);
for(int i=0;i<lim;i++)
a[i]=1ll*a[i]*Inv%mod;
}
inline void Mul(int *a,int *b){
for(int i=0;i<lim;i++)
F[i]=b[i];
NTT(a,1),NTT(F,1);
for(int i=0;i<lim;i++)
a[i]=1ll*a[i]*F[i]%mod;
NTT(a,-1);
}
inline void Sqr(int *a,int *b){
static int F[N];
for(int i=0;i<lim;i++)
F[i]=a[i];
NTT(F,1);
for(int i=0;i<lim;i++)
b[i]=1ll*F[i]*F[i]%mod;
NTT(b,-1);
}
inline void Inv(int *a,int *b,int n){
static int T4[N];
if(n==1){
b[0]=qpow(a[0],mod-2);
return ;
}
Inv(a,b,n+1>>1);
init(n<<1);
for(int i=0;i<n;i++)
T4[i]=a[i];
for(int i=n;i<lim;i++)
T4[i]=0;
NTT(b,1),NTT(T4,1);
for(int i=0;i<lim;i++)
b[i]=1ll*b[i]*(2-1ll*b[i]*T4[i]%mod+mod)%mod;
NTT(b,-1);
for(int i=n;i<lim;i++)
b[i]=0;
}
inline void Der(int *a,int *b,int n){
for(int i=1;i<n;i++)
b[i-1]=1ll*i*a[i]%mod;
b[n-1]=0;
}
inline void Int(int *a,int *b,int n){
for(int i=1;i<n;i++)
b[i]=1ll*a[i-1]*inv[i]%mod;
b[0]=0;
}
inline void Log(int *a,int *b,int n){
for(int i=0;i<lim;i++)
T1[i]=T2[i]=0;
Der(a,T1,n);
Inv(a,T2,n);
Mul(T1,T2);
Int(T1,b,n);
}
inline void Exp(int *a,int *b,int n){
if(n==1){
b[0]=1;
return ;
}
Exp(a,b,n+1>>1);
init(n<<1,0);
for(int i=0;i<lim;i++)
T3[i]=0;
Log(b,T3,n);
for(int i=0;i<n;i++)
T3[i]=(a[i]-T3[i]+mod)%mod;
for(int i=n;i<lim;i++)
b[i]=T3[i]=0;
T3[0]++;
Mul(b,T3);
for(int i=n;i<lim;i++)
b[i]=0;
}
inline void QPow(int *a,int *b,int n,int k1,int k2){//k1:mod p;k2:mod φ(p)
static int T4[N],T5[N];
int fir=0;
for(;fir<n&&!a[fir];fir++);
if(1ll*fir*k1>=n){
for(int i=0;i<n;i++)
b[i]=0;
return ;
}
const int invf=qpow(a[fir],mod-2);
const int powf=qpow(a[fir],k2);
for(int i=0;i<n;i++)
a[i]=1ll*a[i+fir]*invf%mod;
Log(a,T4,n);
for(int i=0;i<n;i++)
a[i]=1ll*T4[i]*k1%mod;
Exp(a,T5,n);
fir*=k1;
for(int i=0;i<fir;i++)
b[i]=0;
for(int i=fir;i<n;i++)
b[i]=1ll*T5[i-fir]*powf%mod;
}
inline void Sqrt(int *a,int *b,int n){
static int T4[N],T5[N];
if(n==1){
b[0]=1;
return ;
}
Sqrt(a,b,n+1>>1);
init(n<<1);
for(int i=0;i<lim;i++)
T4[i]=T5[i]=G[i]=0;
for(int i=0;i<n;i++)
T5[i]=a[i];
Inv(b,T4,n);
Mul(T4,T5);
for(int i=0;i<n;i++)
b[i]=1ll*inv2*(b[i]+T4[i])%mod;
for(int i=n;i<lim;i++)
b[i]=0;
}
}
int k,n;
int T1[N],T2[N],T3[N],T4[N],T5[N];
inline void solve(int n){
for(int i=1;i<n;i++)
T1[i-1]=(1ll*(qpow(k+1,i)-1)*ifac[i])%mod,
T2[i-1]=ifac[i];
Poly::Inv(T2,T3,n);
Poly::Mul(T1,T3);
for(int i=0;i<n;i++)
T1[i]=1ll*T1[i]*fac[i]%mod;
for(int i=1;i<n;i++){
int tmp=1ll*T1[i]*inv[i]%mod;
if(i+1&1) T4[i]=mod-tmp;
else T4[i]=tmp;
}
Poly::Exp(T4,T5,n);
for(int i=0;i<n;i++)
T5[i]=1ll*T5[i]*fac[i]%mod;
}
int main(){
k=read(),n=read()+1;
getG();
Prefix(n+10);
solve(n+10);
for(int i=1;i<n;i++)
write(T5[i]),putc('\n');
flush();
}
再见 qwq~