分类讨论这个数((a_i))翻不翻倍。
若翻倍,则( ext{[)a_i$ ,2(a_i) -1]}(内的数必须翻倍,要不然会影响答案。 若不翻倍,则) ext{[(lceil frac{a_i}{2} ceil), (a_i-1)]}$内的数必须不翻倍,要不然也会影响答案。
剩下的计算可以组合数解决,注意特判(a_i=0)的时候要输出(C_n^k)。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define LOG(...) fprintf (stderr, __VA_ARGS__)
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(), (x).end()
const int INF = 0x3f3f3f3f, MOD = 998244353;
const LL INFL = 0x3f3f3f3f3f3f3f3fll;
const int N = 100005;
int n, k, a[N], b[N], fac[N], ifac[N];
int binom (int n, int m) {
if (n < m || n < 0 || m < 0) return 0;
return 1LL * fac[n] * ifac[n - m] % MOD * ifac[m] % MOD;
}
int inv (int x) {
int t = MOD - 2, res = 1;
while (t) {
if (t&1) res = 1LL * res * x % MOD;
x = 1LL * x * x % MOD;
t >>= 1;
}
return res;
}
void work() {
fac[0] = 1;
for (int i = 1; i <= n; i++) fac[i] = 1LL * fac[i - 1] * i % MOD;
ifac[n] = inv(fac[n]);
for (int i = n-1; i >= 0; i--) ifac[i] = 1LL * ifac[i + 1] * (i + 1) % MOD;
}
int Q (LL x) {
if (x < b[1]) return 0;
int l = 1, r = n, ans = 0;
while (l <= r) {
int mid = (l + r) >> 1;
if (b[mid] <= x) ans = mid, l = mid + 1;
else r = mid - 1;
}
return ans;
}
int add (int a, int b) {
int val = a + b;
if (val >= MOD) val -= MOD;
return val;
}
int main() {
#ifdef LiM_817
freopen ("input.txt", "r", stdin);
// freopen ("test.out", "w", stdout);
double cl = clock();
#endif
cin >> n >> k;
for (int i = 1; i <= n; i++) scanf ("%d", &a[i]), b[i] = a[i];
sort (b + 1, b + n + 1);
work();
for (int i = 1; i <= n; i++) {
if (!a[i]) {
printf ("%d
", binom (n, k));
continue;
}
int ans = 0;
// case 1
int Lb = a[i] / 2 + (a[i] % 2), Rb = a[i] - 1;
if (Lb > Rb) ans = add(ans, binom (n - 1, k));
else {
int q = Q(Rb) - Q(Lb - 1);
ans = add(ans, binom (n - 1 - q, k));
}
Lb = a[i], Rb = 2 * a[i] - 1;
if (Lb > Rb) ans = add (ans, binom (n - 1, k - 1));
else {
int q = Q(Rb) - Q(Lb - 1);
ans = add (ans, binom (n - q, k - q));
}
printf ("%d
", ans);
}
#ifdef LiM_817
cerr << fixed << setprecision(2) << "Time ellapsed: " << ((double)(clock() - cl) / CLOCKS_PER_SEC) << "s
";
#endif
return 0;
}