【题目泛做】集合(数学推导)

简要题意:

有集合 [ n ] = { 1 , 2 , 3 , … , n } [n]=\{1,2,3,\dots,n\} [n]={1,2,3,,n},请你求出 E ( A min ⁡ ( S ) ∣ S ⊆ [ n ] , ∣ S ∣ = k ) E(A^{\min(S)}|S\subseteq [n],|S|=k) E(Amin(S)S[n],S=k)

n n n 没有限制, k ≤ 1 e 7 k\leq 1e7 k1e7


题解:

容易发现我们要求的实际上就是 F ( k ) = ∑ S ⊆ [ n ] , ∣ S ∣ = k A min ⁡ ( S ) F(k)=\sum\limits_{S\subseteq [n],|S|=k}A^{\min(S)} F(k)=S[n],S=kAmin(S)

枚举最小值可以得到 F ( k ) = ∑ i = 1 n A i ( n − i k − 1 ) F(k)=\sum_{i=1}^nA^i{n-i\choose k-1} F(k)=i=1nAi(k1ni)

我们希望能够推到边界情况 F ( 1 ) F(1) F(1) F ( n ) F(n) F(n),容易发现 F ( n ) = A F(n)=A F(n)=A 比较简单,考虑推到 k + 1 k+1 k+1

利用 ∑ j = 0 i − 1 A j = A i − 1 A − 1 \sum_{j=0}^{i-1}A^j=\frac{A^i-1}{A-1} j=0i1Aj=A1Ai1(注意这里要特判掉 A = 1 A=1 A=1 的情况,直接输出 1 1 1),把上面的 A i A^i Ai 换掉。

步骤省略,最后可以得到 F ( k ) = F ( k + 1 ) ( A − 1 ) + A ( n k ) F(k)=F(k+1)(A-1)+A{n\choose k} F(k)=F(k+1)(A1)+A(kn), 有边界情况 F ( n ) = A F(n)=A F(n)=A

很显然可以得到通项为 F ( k ) = ∑ i = k n A ( A − 1 ) i − k ( n i ) F(k)=\sum\limits_{i=k}^nA(A-1)^{i-k}{n\choose i} F(k)=i=knA(A1)ik(in),再把 A ( A − 1 ) − k {A(A-1)^{-k}} A(A1)k 提出来,后面由二项式定理就是 A n − ∑ i = 0 k ( A − 1 ) i ( n i ) A^n-\sum_{i=0}^k(A-1)^i{n\choose i} Ani=0k(A1)i(in),直接 O ( k ) O(k) O(k) 求一下即可。


代码:

#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const

using std::cerr;
using std::cout;

cs int mod=998244353;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(int a,int b){return a-b<0?a-b+mod:a-b;}
inline int mul(int a,int b){ll r=(ll)a*b;return r>=mod?r%mod:r;}
inline void Inc(int &a,int b){a+=b-mod;a+=a>>31&mod;}
inline void Dec(int &a,int b){a-=b;a+=a>>31&mod;}
inline void Mul(int &a,int b){a=mul(a,b);}
inline int po(int a,int b){int r=1;for(;b;b>>=1,Mul(a,a))if(b&1)Mul(r,a);return r;}
inline void ex_gcd(int a,int b,int&x,int &y){
	if(!b){x=1,y=0;return;}ex_gcd(b,a%b,y,x);y-=a/b*x;
}inline int Inv(int a){int x,y;ex_gcd(mod,a,y,x);return x+(x>>31&mod);}

cs int N=1e7+7;

int n,k,A;
int ifc[N],dn[N];

int Cn(int m){
	return mul(dn[m],ifc[m]);
}

void Main(){
	scanf("%d%d%d",&n,&k,&A);
	if(A==1){cout<<1<<"\n";return;}
	for(int re i=dn[0]=1;i<=k;++i)
		dn[i]=mul(dn[i-1],n-i+1);
	ifc[0]=ifc[1]=1;
	for(int re i=2;i<=k;++i)
		ifc[i]=mul(mod-mod/i,ifc[mod%i]);
	for(int re i=2;i<=k;++i)
		Mul(ifc[i],ifc[i-1]);
	int res=po(A,n);int pw=1;
	for(int re i=0;i<k;++i){
		Dec(res,mul(pw,Cn(i)));
		Mul(pw,A-1);
	}Mul(res,A),Mul(res,po(Inv(A-1),k));
	cout<<mul(res,Inv(Cn(k)))<<"\n";
}

inline void file(){
#ifdef zxyoi
	freopen("set.in","r",stdin);
#else
#ifndef ONLINE_JUDGE
	freopen("set.in","r",stdin);
	freopen("set.out","w",stdout);
#endif
#endif
}signed main(){file();Main();return 0;}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值