题目描述
EGF
普通生成函数(OGF)(F(x)=sum a_ix^i)
对应的指数型生成函数(EGF)(G(x)=sum frac{a_ix^i}{i!})
用于解决组合问题,两个指数型生成函数相乘时
(A(x)B(x)=sum a_ib_jfrac{x^{i+j}}{i!j!}=sum inom{i+j}{i}a_ib_jfrac{x^{i+j}}{(i+j)!}),即组合时会乘上一个组合数(i+j,j)
简单应用:
证明(sum i(n-i)inom{n}{i}=2^{n-2}n(n-1))
(sum frac{ix^i}{i!}=xsum_{i>=1} frac{x^i}{i!}=xe^x)
所以原式=([x^n]x^2e^{2x}=[x^n]sum{frac{2^ix^{i+2}}{i!}}),提出来就是(frac{2^{n-2}x^n}{(n-2)!}),转回OGF即为(2^{n-2}n(n-1)x^n)
题解
膜lk:https://qaq-am.com/UOJ514/#comment-18
特地用黑体标出来误导的屑(
由于考虑了这个所以只想到了n^4log的dp+FFT,其实把限制去掉和原问题等价
证明:对于当前的一种状态,设选到>=a的概率为p,加上不选的限制后的答案为s
那么去掉限制之后的答案为((1-p)s+p(1-p)s+p^2(1-p)s+...)
求和等于((1-p)frac{p^infty -1}{p-1}=(1-p)frac{1}{1-p}=1),因此贡献不变
最后一个放的舱一定为b,考虑枚举这个舱并计算其他>=a的贡献
因此要乘上n(n-1),但是最后一步的概率是1/n,所以实际乘的是n-1
设(S_i=frac{(frac{x}{n})^i}{i!}),由于长度没有上限了,所以实际求的是
((n-1)(e^{frac{x}{n}}-sum_{i<a}S_i)(e^{frac{x}{n}}-sum_{i<b}S_i)^{n-2}S_{b-1})
的OGF(F(x))的所有项之和,即(F(1))
把二项式拆开,变成求若干(e^{ax}frac{x^b}{b!})的OGF的F(1)
(e^{ax}frac{x^b}{b!}=sum frac{a^ix^{i+b}}{b!i!}=sum inom{i+b}{b}frac{a^ix^{i+b}}{(i+b)!})
所以OGF为(F(x)=sum inom{i+b}{b}a^ix^{i+b}=frac{x^b}{(1+ax)^{b+1}})
直接求即可,多项式项数为na,二项式展开为n,所以时间是(O(n^2alog(na)))
简单卡常+register即可
code
998244353的模数有3和114514
#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define C(n,m) (jc[n]*Jc[m]%998244353*Jc[(n)-(m)]%998244353)
#define ll long long
#define mod 998244353
#define Mod 998244351
#define G 114514
//#define file
using namespace std;
ll jc[62501],Jc[62501],ww[62501],p[62501],a[65536],b[65536],c[65536],d[65536],w[17][65536],W[17][65536],ans,Ans,s,S;
int a2[65536],m,n,A,B,i,j,k,l,N,N2,len;
ll qpower(ll a,int b) {ll ans=1; while (b) {if (b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;} return ans;}
void init()
{
ll w,w2,W,W2;
jc[0]=jc[1]=Jc[0]=Jc[1]=ww[1]=p[0]=1;
fo(i,2,62500) ww[i]=mod-ww[mod%i]*(mod/i)%mod,jc[i]=jc[i-1]*i%mod,Jc[i]=Jc[i-1]*ww[i]%mod;
fo(i,1,62500) p[i]=p[i-1]*ww[n]%mod;
fo(i,0,N-1)
{
j=i,k=0;
fo(l,1,len)
k=k*2+(j&1),j>>=1;
a2[i]=k;
}
l=2;k=1;
fo(i,1,len)
{
w2=qpower(G,(mod-1)/l),W2=qpower(G,(mod-1)-(mod-1)/l);w=W=1;
fo(j,0,k-1) ::w[i][j]=w,::W[i][j]=W,w=w*w2%mod,W=W*W2%mod;
l<<=1;k<<=1;
}
}
void dft(ll *a,int tp)
{
static ll A[65536];
register int i,j,k,l,S=N,s1=2,s2=1;
ll u,v;
fo(i,0,N-1) A[a2[i]]=a[i];
memcpy(a,A,N*8);
fo(i,1,len)
{
S>>=1;
fo(j,0,S-1)
{
fo(k,0,s2-1)
{
u=a[j*s1+k],v=a[j*s1+k+s2]*((tp==1)?w[i][k]:W[i][k]);
a[j*s1+k]=(u+v)%mod;
a[j*s1+k+s2]=(u-v)%mod;
}
}
s1<<=1,s2<<=1;
}
}
void Mul(ll *a,ll *b) {int i;fo(i,0,N-1) a[i]=a[i]*b[i]%mod;}
void turn(ll *a) {int i;fo(i,0,N-1) a[i]=a[i]*N2%mod;}
void mul(ll *a,ll *b)
{
static ll c[65536];
int i;
memcpy(c,b,N*8);
dft(a,1),dft(c,1);
Mul(a,c);
dft(a,-1);
turn(a);
}
ll js(ll a,ll b) {return qpower(1-a,(mod-1)-(b+1));}
void work()
{
fo(i,0,A-1) a[i]=-Jc[i]*p[i]%mod;b[B-1]=Jc[B-1]*p[B-1]%mod,dft(a,1),dft(b,1),Mul(b,a);
memset(a,0,sizeof(a));
a[B-1]=Jc[B-1]*p[B-1]%mod,dft(a,1);
fo(i,0,B-1) c[i]=-Jc[i]*p[i]%mod;dft(c,1);
fo(i,0,n-2)
{
Ans=0;
memcpy(d,a,N*8),dft(d,-1),turn(d),s=1,S=qpower(1-ww[n]*(n-1-i)%mod,Mod);
fo(j,0,m) s=s*S%mod,Ans=(Ans+s*(d[j]*jc[j]%mod))%mod;
memcpy(d,b,N*8),dft(d,-1),turn(d),s=1,S=qpower(1-ww[n]*(n-2-i)%mod,Mod);
fo(j,0,m) s=s*S%mod,Ans=(Ans+s*(d[j]*jc[j]%mod))%mod;
ans=(ans+Ans*C(n-2,i))%mod;
if (i<n-2) Mul(a,c),Mul(b,c);
}
}
int main()
{
#ifdef file
freopen("uoj514.in","r",stdin);
#endif
scanf("%d%d%d",&n,&A,&B),len=ceil(log2(n*A+1)),N=qpower(2,len),N2=qpower(N,Mod),m=n*A;
if (n==1) {printf("1
");return 0;}
init();
work();
ans=(ans+mod)%mod;
printf("%lld
",ans*(n-1)%mod);
fclose(stdin);
fclose(stdout);
return 0;
}