先考虑正着做,我们只考虑整个 \(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
标签:Count,Supersequences,int,res,fpow,1ll,CF1838E,fac,binom
From: https://www.cnblogs.com/jucason-xu/p/17458625.html