#514. 【UR #19】通用测评号(EGF初涉)
题目描述
EGF
普通生成函数(OGF)\(F(x)=\sum a_ix^i\)
对应的指数型生成函数(EGF)\(G(x)=\sum \frac{a_ix^i}{i!}\)
用于解决组合问题,两个指数型生成函数相乘时
\(A(x)B(x)=\sum a_ib_j\frac{x^{i+j}}{i!j!}=\sum \binom{i+j}{i}a_ib_j\frac{x^{i+j}}{(i+j)!}\),即组合时会乘上一个组合数(i+j,j)
简单应用:
证明\(\sum i(n-i)\binom{n}{i}=2^{n-2}n(n-1)\)
\(\sum \frac{ix^i}{i!}=x\sum_{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/
特地用黑体标出来误导的屑(
由于考虑了这个所以只想到了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 \binom{i+b}{b}\frac{a^ix^{i+b}}{(i+b)!}\)
所以OGF为\(F(x)=\sum \binom{i+b}{b}a^ix^{i+b}=\frac{x^b}{(1+ax)^{b+1}}\)
直接求即可,多项式项数为na,二项式展开为n,所以时间是\(O(n^2a\log(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\n");return 0;}
init();
work();
ans=(ans+mod)%mod;
printf("%lld\n",ans*(n-1)%mod);
fclose(stdin);
fclose(stdout);
return 0;
}