洛谷 P6031 - CF1278F Cards 加强版(推式子+递推)

洛谷题面传送门

u1s1 这个推式子其实挺套路的吧,可惜有一步没推出来看了题解

\[\begin{aligned} res&=\sum\limits_{i=0}^ni^k\dbinom{n}{i}(\dfrac{1}{m})^i(\dfrac{m-1}{m})^{n-i}\\ &=\sum\limits_{i=0}^n\sum\limits_{j=1}^k\begin{Bmatrix}k\\j\end{Bmatrix}i^{\underline{j}}\dbinom{n}{i}(\dfrac{1}{m})^i(\dfrac{m-1}{m})^{n-i}\\ &=(\dfrac{m-1}{m})^{n}\sum\limits_{i=0}^n\sum\limits_{j=1}^k\begin{Bmatrix}k\\j\end{Bmatrix}i^{\underline{j}}\dbinom{n}{i}(\dfrac{1}{m-1})^i\\ &=(\dfrac{m-1}{m})^{n}\sum\limits_{i=0}^n\sum\limits_{j=1}^k\begin{Bmatrix}k\\j\end{Bmatrix}i^{\underline{j}}\dbinom{n}{i}(\dfrac{1}{m-1})^i\\ &=(\dfrac{m-1}{m})^{n}\sum\limits_{j=1}^k\begin{Bmatrix}k\\j\end{Bmatrix}j!\sum\limits_{i=0}^n\dbinom{i}{j}\dbinom{n}{i}(\dfrac{1}{m-1})^i\\ &=(\dfrac{m-1}{m})^{n}\sum\limits_{j=1}^k\begin{Bmatrix}k\\j\end{Bmatrix}j!\dbinom{n}{j}(\dfrac{1}{m-1})^j\sum\limits_{i=0}^{n-j}\dbinom{n-j}{i-j}(\dfrac{1}{m-1})^i\\ &=(\dfrac{m-1}{m})^{n}\sum\limits_{j=1}^k\begin{Bmatrix}k\\j\end{Bmatrix}j!\dbinom{n}{j}(\dfrac{1}{m-1})^j(\dfrac{m}{m-1})^{n-j}\\ &=\sum\limits_{j=1}^k\begin{Bmatrix}k\\j\end{Bmatrix}j!\dbinom{n}{j}(\dfrac{1}{m})^j\\ &=\sum\limits_{j=1}^k\sum\limits_{l=0}^j\dbinom{j}{l}l^k(-1)^{j-l}\dbinom{n}{j}(\dfrac{1}{m})^j\\ &=\sum\limits_{l=0}^jl^k\sum\limits_{j=1}^k\dbinom{j}{l}(-1)^{j-l}\dbinom{n}{j}(\dfrac{1}{m})^j\\ &=\sum\limits_{l=0}^kl^k\dbinom{n}{l}\sum\limits_{j=l}^k(-1)^{j-l}\dbinom{n-l}{j-l}(\dfrac{1}{m})^j\\ \end{aligned} \]

前面那东西我们要枚举 \(l\),复杂度自然有一个 \(k\),后面那东西看似可以二项式定理,但是由于上界为 \(k\) 而不是 \(n\),实则不能,因此考虑按照套路进行递推,设 \(f_l\)​ 表示

\[f_l=\sum\limits_{j=l}^k(-1)^{j-l}\dbinom{n-l}{j-l}(\dfrac{1}{m})^j \]

那么

\[\begin{aligned} f_{l-1}&=\sum\limits_{j=l-1}^k(-1)^{j-l+1}\dbinom{n-l+1}{j-l+1}(\dfrac{1}{m})^j\\ &=-\sum\limits_{j=l-1}^k(-1)^{j-l}\dbinom{n-l+1}{j-l+1}(\dfrac{1}{m})^j\\ &=-\sum\limits_{j=l-1}^k(-1)^{j-l}\dbinom{n-l}{j-l+1}(\dfrac{1}{m})^j-\sum\limits_{j=l-1}^k(-1)^{j-l}\dbinom{n-l}{j-l}(\dfrac{1}{m})^j\\ &=-\sum\limits_{j=l}^{k+1}(-1)^{j-1-l}\dbinom{n-l}{j-l}(\dfrac{1}{m})^{j-1}-\sum\limits_{j=l-1}^k(-1)^{j-l}\dbinom{n-l}{j-l}(\dfrac{1}{m})^j\\ &=m\sum\limits_{j=l}^{k+1}(-1)^{j-l}\dbinom{n-l}{j-l}(\dfrac{1}{m})^{j}-\sum\limits_{j=l-1}^k(-1)^{j-l}\dbinom{n-l}{j-l}(\dfrac{1}{m})^j\\ &=m(\sum\limits_{j=l}^{k}(-1)^{j-l}\dbinom{n-l}{j-l}(\dfrac{1}{m})^{j}+(-1)^{k+1-l}\dbinom{n-l}{k+1-l}(\dfrac{1}{m})^{k+1})-\sum\limits_{j=l}^k(-1)^{j-l}\dbinom{n-l}{j-l}(\dfrac{1}{m})^j\\ &=m(f_l+(-1)^{k+1-l}\dbinom{n-l}{n-k-1}(\dfrac{1}{m})^{k+1})-f_l \end{aligned} \]

从后往前一遍递推即可。\(\text{id}_k\) 可以一遍线筛筛出,复杂度 \(\mathcal O(k)\)

至于我是哪里被卡住了呢……在第一个公式的第七个等于号那边,我上来就想拆开来递推,然后发现递推完了要套好几层,然后就 quit 了。事实证明一般只有只带一个组合数的式子才能递推求解。

那么问题就来了,为什么我的 \(\mathcal O(k)\) 跑不过 \(\mathcal O(k\log k)\)/yun/yun

const int MAXK=1e7+1;
const int MOD=998244353;
int n,m,k;
int qpow(int x,int e){
	int ret=1;
	for(;e;e>>=1,x=1ll*x*x%MOD) if(e&1) ret=1ll*ret*x%MOD;
	return ret;
}
int fac[MAXK+5],ifac[MAXK+5],f[MAXK+5],inv[MAXK+5];
void init_fac(int n){
	for(int i=(fac[0]=ifac[0]=inv[0]=inv[1]=1)+1;i<=n;i++) inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
	for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%MOD,ifac[i]=1ll*ifac[i-1]*inv[i]%MOD;
}
int pwk[MAXK+5],pr[MAXK/10+5],prcnt=0;
bitset<MAXK+5> vis;
void sieve(int n){
	pwk[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i]) pwk[i]=qpow(i,k);
		for(int j=1;j<=prcnt&&pr[j]*i<=n;j++){
			vis[pr[j]*i]=1;pwk[pr[j]*i]=1ll*pwk[pr[j]]*pwk[i]%MOD;
			if(i%pr[j]==0) break;
		}
	}
}
int main(){
	init_fac(MAXK);int res=0;
	scanf("%d%d%d",&n,&m,&k);sieve(k+1);
	int ivm=qpow(m,MOD-2),pw=qpow(ivm,k+1);
	for(int l=k+1,cur=1;l>=2;l--){
		int t=1ll*cur*pw%MOD;
//		printf("%d\n",cur);
		if((k+1-l)&1) f[l-1]=(1ll*m*(f[l]-t+MOD)%MOD-f[l]+MOD)%MOD;
		else f[l-1]=(1ll*m*(f[l]+t)%MOD-f[l]+MOD)%MOD;
		cur=1ll*cur*(n-l+1+MOD)%MOD*inv[k+2-l]%MOD;
	}
	for(int l=1,cur=n;l<=k;l++){
		res=(res+1ll*f[l]*pwk[l]%MOD*cur)%MOD;
		cur=1ll*cur*(n-l)%MOD*inv[l+1]%MOD;
	} printf("%d\n",res);
	return 0;
}
posted @ 2021-08-19 11:31  tzc_wk  阅读(59)  评论(1编辑  收藏  举报