考虑 n 个数都互不相同的情况,此时任意拿出一个子序列都不会发生重复,答案就是一个组合数:Cn k。
考虑有 n−1个数互不相同的情况,那么会出现一种重复的情况:两个相同的数选其一,并且它们之间不再选其他数字。
比如:[1,2,3,4,5,3,6]。如果我们选出一个子序列 [1,3] ,此时选的是第一个三还是第二个三就不确定,出现重复,如果是 [1,3,4] 我们就可以定位到此时选了第一个三。
因此,在求出 Cnk 总的方案数,减去重复情况:重复数字选其一,然后在除了重复数字之间的数中把剩下 k−1 个选完,也就是 Cn−1−(possecond−posfirst) k−1
需要注意要保证 k−1≤n−1−possecond+posfirst,否则不可能出现重复(子序列太长,一定会选至少一个相同数之间的元素)。
代码:
#include <bits/stdc++.h>
#define int long long
#define fi first
#define se second
using namespace std;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const int N = 1e5+5;
int n,k;
int a[N];
map<int,int>mp;
int fact[N],infact[N];
int qmi(int a,int b,int mod){
int res = 1;
while(b){
if(b&1)res=(res*a)%mod;
b>>=1;
a = (a*a)%mod;
}
return res;
}
int C(int a,int b){
return fact[a]*infact[b]%mod*infact[a-b]%mod;
}
void solve(){
cin>>n>>k;
mp.clear();
for(int i=1;i<=n;i++)cin>>a[i];
if(n==k){
cout<<1<<"\n";
return;
}
int ans = C(n,k);
for(int i=1;i<=n;i++){
if(!mp[a[i]]){
mp[a[i]] = i;
}
else{
if(n-1-(i-mp[a[i]])>=k-1)ans = (ans- C(n-1-(i-mp[a[i]]),k-1)+mod)%mod;
mp[a[i]] = i;
}
}
cout<<ans<<"\n";
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
fact[0]=infact[0]=1;
for(int i=1;i<N;i++){
fact[i]=fact[i-1]*i%mod;
infact[i]=infact[i-1]*qmi(i,mod-2,mod)%mod;
}
int t=1;cin>>t;
while(t--){
solve();
}
return 0;
}