CF1838E - Count Supersequences

先考虑正着做,我们只考虑整个 \(b\) 序列中出现的第一个子序列 \(a\)

这样,我们就是要往 \(a\) 中插入 \(m-n\) 个数,其中 \(a_{i-1}\)\(a_i\) 之间不能有 \(a_i\)(否则就会有更靠前的子序列)。\(a_1\) 前面不能有 \(a_1\)\(a_n\) 后面什么都可以有。

我们发现,我们可以先枚举 \(a_n\) 前面有多少个数,\(a_n\) 前面的数的值域都是 \(k-1\),具体哪一种不能选取决于其后面的一个 \(a\),但是无关紧要。\(a_n\) 后面填什么都行。对于前面的,还要分成 \(n\) 段(允许为空),可以直接扩展插板法。

所以,答案就是 \(\sum_{i=0}^m\binom{n-1+i}{i}(k-1)^ik^{m-i}\)。但是我们发现这样要枚举 \(i\) 是不能接受的。

考虑这个做法最麻烦的地方在哪里,就是最后一段填什么都行。消掉这个限制,即考虑正难则反,计算包含 \(a\) 的前缀 \(i\) 且不包含 \(a\) 的前缀 \(i+1\) 的方案数。这样,总的答案就是 \(k^m-\sum_{i=0}^{n-1}f(i)\)\(f(i)\) 很好计算,因为这个时候,\(a_i\) 后面也有了值域不能是 \(a_{i+1}\) 的限制,大家的值域都是 \(k-1\),所以 \(f(i)=\binom{m}{i}(k-1)^i\)

这时还有最后一个问题,计算 \(\binom{m}{i}\),发现 \(\binom{m}{i}=\dfrac{m!}{i!(m-i)!}=\dfrac{m!}{(i-1)!(m-i+1)!}\dfrac{m-i+1}{i}=\dfrac{m-i+1}{i}\binom{m}{i-1}\),也就可以根据上一次的递推计算,起点是 \(\binom{m}{0}=1\)

也就可以计算了。

const int P=1000000007;
int n,m,k,a[200005],fac[200005],ifac[200005];
inline int fpow(int a,int p){
	if(!p)return 1;
	int res=fpow(a,p>>1);
	if(p&1)return 1ll*res*res%P*a%P;
	return 1ll*res*res%P;
}
inline void init(){
	fac[0]=ifac[0]=1;
	rep(i,1,200000)fac[i]=1ll*fac[i-1]*i%P;
	rep(i,1,200000)ifac[i]=fpow(fac[i],P-2);
}
inline int C(int n,int m){
	return 1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;
}
inline void solve(){
	cin>>n>>m>>k;
	rp(i,n)cin>>a[i];
	int ans=fpow(k,m),res=1;
	rep(i,0,n-1){
		if(i)res=1ll*res*fpow(i,P-2)%P*(m-i+1)%P;
		ans=(ans-1ll*res%P*fpow(k-1,m-i)%P+P)%P;
	}cout<<ans<<endl;
} 
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t;cin>>t;
	init();
	rd(_,t)solve();
	return 0;
}
//Nyn-siyn-hert
posted @ 2023-06-05 18:02  jucason_xu  阅读(35)  评论(0编辑  收藏  举报