简要题意:
有集合 [ 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 k≤1e7
题解:
容易发现我们要求的实际上就是 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∣=k∑Amin(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(k−1n−i)。
我们希望能够推到边界情况 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=0i−1Aj=A−1Ai−1(注意这里要特判掉 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)(A−1)+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=k∑nA(A−1)i−k(in),再把 A ( A − 1 ) − k {A(A-1)^{-k}} A(A−1)−k 提出来,后面由二项式定理就是 A n − ∑ i = 0 k ( A − 1 ) i ( n i ) A^n-\sum_{i=0}^k(A-1)^i{n\choose i} An−∑i=0k(A−1)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;}