#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;
}
posted @ 2020-07-15 22:47  gmh77  阅读(289)  评论(0编辑  收藏  举报