CF1278F题解

这不是傻逼题吗??????

考虑到第一张是王牌的概率为 1m,答案就是:

i=0n(ni)(1m)i(11m)niik

我们设 f(x)=xk,x=1m

i=0n(ni)f(i)xi(1x)ni

然后变成 LGP6667 如何优雅地求和。

那题的瓶颈在于转化下降幂多项式,这题轻松计算出点值,然后随便一卷就行了。

复杂度 O(klogk)

这个在原题是存在线性做法的。

然后考虑做到 O(k)

把柿子写出来:i=0kfini_xi

计算点值对其的贡献:

f(i)i!ex=f(i)i!j=0mi(1)jj!xi+j

丢到上面的柿子里面就是:

1i!j=im(1)ji(ji)!nj_xj

1i!j=im(1)ji(ji)!ni_(ni)ji_xj

ni_i!j=0mi(nij)(1)jxi+j

考虑后面这个玩意儿 gk=i=0mk(nki)(1)ixi+k

直接把组合数拆成递推:

i=0mk(nk1i)(1)ixi+k+i=1mk(nk1i1)(1)ixi+k

(1)mi(nk1mk)xm+1xgk+1gk+1

特判 m=1,然后没了。

别忘了这是点值的贡献,答案是 i=0kikgi

代码基本上是贺的sk的,别看了

#include<cstdio>
typedef unsigned ui;
const ui M=1e7+5,mod=998244353;
ui n,m,k,top,g[M],pri[M],idk[M],inv[M],ifac[M];bool zhi[M];
inline ui pow(ui a,ui b){
	ui ans(1);for(;b;b>>=1,a=1ull*a*a%mod)if(b&1)ans=1ull*ans*a%mod;return ans;
}
inline void sieve(const ui&M){
	idk[1]=1;
	for(ui i=2;i<=M;++i){
		if(!zhi[i])pri[++top]=i,idk[i]=pow(i,k);
		for(ui x,j=1;j<=top&&(x=i*pri[j])<=M;++j){
			idk[x]=1ull*idk[i]*idk[pri[j]]%mod;if(!(i%pri[j]))break;
		}
	}
}
signed main(){
	ui ans(0);
	scanf("%u%u%u",&n,&m,&k);
	if(m==1)return printf("%u",pow(n,k)),0;
	m=pow(m,mod-2);sieve(k);inv[0]=inv[1]=1;ifac[0]=1;
	for(ui i=2;i<=k;++i)inv[i]=1ull*(mod-mod/i)*inv[mod%i]%mod;
	for(ui i=1;i<=k;++i)ifac[i]=1ull*ifac[i-1]*inv[i]%mod;
	ui c1(1),c2(pow(m-1,mod-2));
	for(ui i=0;i<=k;++i){
		if(i&1)g[0]=(g[0]+1ull*(mod-c1)*ifac[i])%mod;
		else g[0]=(g[0]+1ull*c1*ifac[i])%mod;
		c1=1ull*c1*m%mod*(mod+n-i)%mod;
	}
	for(ui i=1;i<=k;++i){
		g[i]=((mod+n-i+1ull)*m%mod*g[i-1]+1ull*ifac[i-1]*ifac[k-i+1]%mod*(k-i&1?mod-c1:c1))%mod*(mod-c2)%mod*inv[i]%mod;
	}
	for(ui i=1;i<=k;++i)ans=(ans+1ull*idk[i]*g[i])%mod;
	printf("%u",ans);
}

本文作者:Prean

本文链接:https://www.cnblogs.com/lmpp/p/15957369.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Prean  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
var canShowAdsense=function(){return !!0};
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起