Codeforces Round 964 (Div. 4)
注册了一个新的小号打了一把,大部分时间其实都在 \(in \ queue\),\(G1,G2\) 的三分多了一次重复询问,甚至半个多小时才看出来。搞笑的是我忘了题目是多测,然后就一直提交一直 \(Wrong \ answer \ in \ test \ 1\)。这场的题目整体来说比以前简单很多啊,感觉 \(Specialist\) 应该都能随便 \(AK\) 啊。
感觉 \(F\) 题是唯一比较有意思的题,大概是一点点组合数学吧,代码不难写,有板子的话应该会很快。题目的意思是给一个 \(0\)\(1\) 序列,问这个序列的所有指定长度非连续子序列的中位数的和是多少。数一下 \(0\) 和 \(1\) 的数量,显然当 \(0\) 作为中位数时对答案是没有贡献的,所以中位数一定是 \(1\),然后暴力枚举一下这个 \(1\) 前面有多少个 \(1\) 就可以了。记得特判一下全 \(0\) 序列。
#pragma GCC optimize("unroll-loops, Ofast")
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
#define endl '\n'
#define lowbit(x) x & -x
constexpr i64 Mod = 1000000007;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
i64 n, m, k;
void init() {}
class Z {
using i64 = long long;
static const i64 Mod = 1000000007;
public:
i64 num;
Z() = default;
Z(i64 _num) : num((_num % Mod + Mod) % Mod) {}
i64 val() const {
return num;
}
Z &operator = (i64 b) {
return *this = Z(b);
}
friend bool operator < (Z a, Z b) {
return a.num < b.num;
}
friend bool operator >(Z a, Z b) {
return a.num > b.num;
}
friend bool operator <=(Z a, Z b) {
return a.num <= b.num;
}
friend bool operator>=(Z a, Z b) {
return a.num >= b.num;
}
friend bool operator==(Z a, Z b) {
return a.num == b.num;
}
friend Z operator + (Z a, Z b) {
return Z((a.num + b.num) % Mod);
}
friend Z &operator += (Z &a,Z b) {
return a = a + b;
}
friend Z operator + (Z a, i64 b) {
return a + Z(b);
}
friend Z &operator += (Z &a, i64 b) {
return a = a + b;
}
friend Z &operator ++ (Z &a) {
return a += 1;
}
friend Z operator ++ (Z &a, int) {
Z copy(a);
a += 1;
return copy;
}
friend Z operator - (Z a, Z b) {
return Z(((a.num - b.num) % Mod + Mod) % Mod);
}
friend Z &operator -= (Z &a, Z b) {
return a = a - b;
}
friend Z operator - (Z a, i64 b) {
return a - Z(b);
}
friend Z &operator -= (Z &a, i64 b) {
return a = a - b;
}
friend Z &operator -- (Z &a) {
return a -= 1;
}
friend Z operator -- (Z &a, int) {
Z copy(a);
a -= 1;
return copy;
}
friend Z operator * (Z a, Z b) {
return Z((long long)a.num * b.num % Mod);
}
friend Z &operator *= (Z &a, Z b) {
return a = a * b;
}
friend Z operator * (Z a, i64 b) {
return a * Z(b);
}
friend Z &operator *= (Z &a, i64 b) {
return a = a * b;
}
Z inv() {
i64 ans = 1;
i64 a = num;
i64 b = Mod - 2;
while (b) {
if (b & 1) ans = ans * a % Mod;
a = a * a % Mod;
b >>= 1;
}
return Z(ans);
}
friend Z operator / (Z a, Z b) {
return a * b.inv();
}
friend Z &operator /= (Z &a, Z b) {
return a = a / b;
}
friend Z operator / (Z a, i64 b) {
return a / Z(b);
}
friend Z &operator /= (Z &a, i64 b) {
return a = a / b;
}
friend std::istream &operator>>(std::istream &is, Z &a) {
int v;
is >> v;
a = Z(v);
return is;
}
friend std::ostream &operator<<(std::ostream &os, const Z &a) {
return os << a.val();
}
};
struct Comb {
using i64 = long long;
const i64 N, mod = 1000000007;
vector<i64> fac, invfac;
Comb(i64 n) : N(n), fac(n + 2), invfac(n + 2) { init(); };
Comb(int n) : N(n), fac(n + 2), invfac(n + 2) { init(); };
Comb(double n) : N(i64(n)), fac(i64(n) + 2), invfac(i64(n) + 2) { init(); };
i64 qpow(i64 x, i64 p) {
i64 res = 1 % mod; x %= mod;
for (; p; p >>= 1, x = x * x % mod)
if (p & 1) res = res * x % mod;
return res;
}
i64 inv(i64 x) { return qpow(x, mod - 2); };
void init() {
fac[0] = 1;
for (i64 i = 1; i <= N; ++i) fac[i] = fac[i - 1] * i % mod;
invfac[N] = inv(fac[N]);
for (i64 i = N - 1; i >= 0; --i) invfac[i] = (invfac[i + 1] * (i + 1)) % mod;
}
i64 C(i64 n, i64 m) {
if (!n) {
return 1;
}
if (n < m || m < 0) return 0;
return fac[n] * invfac[m] % mod * invfac[n - m] % mod;
}
i64 A(i64 n, i64 m) {
if (n < m || m < 0) return 0;
return fac[n] * invfac[n - m] % mod;
}
};
constexpr int N = 2e5 + 5;
Comb inv(N);
void solve() {
cin >> n >> k;
int u = 0, v = 0;
vector<int> p(n + 1);
for (int i = 1; i <= n; i++) {
cin >> p[i];
u += (p[i] == 0);
v += (p[i] != 0);
}
if (v < (k - 1) / 2) {
cout << 0 << endl;
return ;
}
Z ans = 0;
for (int i = (k + 1) / 2; i <= k, i <= v; i++) {
if (k - i > u || !u) {
continue;
}
ans += inv.C(v, i) * inv.C(u, k - i);
}
if (!u && v >= k) {
ans += inv.C(v, k);
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
init();
int t = 1;
cin >> t;
while (t--) {
solve();
}
return 0;
}