Pregunta

image.pngimage.png

Реши на с++

Pensamiento

Optimizing with precomputation

To optimize the calculation, I'll compute the values modulo 998244353. I’ll precompute factorials and inverse factorials up to k to calculate binomial coefficients quickly. Each power operation will utilize repeated squaring for efficiency. The complexity of performing 4.5 million power operations is manageable in C++, though I'll keep an eye on performance.

Optimizing with squaring and precomputation

I’ll use exponentiation by squaring to optimize the power operations, handling unique bases across r. Still, about 12 multiplications per power calls, but it’s manageable. Considering edge cases, I’ll precompute the B[m] values and calculate the final answer with inclusion-exclusion using binomial coefficients. We’ll handle all values mod 998244353.

Avoiding inefficient binomial calculations

To avoid recomputing binomial coefficients multiple times, I’ll use factorial and inverse factorial arrays. First, I’ll precompute them up to k, then calculate the binomial coefficients with those. The B array is computed by summing powers of the binomials across r for each m, leading to a final result via inclusion-exclusion.

Thought for 3m 6s

Respuesta

Вот аккуратное решение.

Идея: нумеруем друзей 1..n1..n, фотографии — это векторы-столбцы vj{0,1}nv_j\in\{0,1\}^n (пустая колонка запрещена). Требуется посчитать число последовательностей из kk столбцов, где все суммарные вхождения по строкам одинаковы: jvij=r\sum_j v_{ij}=r для всех ii (какое-то 0rk0\le r\le k).

Сделаем включение–исключение по «пустым» столбцам. Пусть из kk столбцов ровно ss фиксируем пустыми. Тогда остаётся m=ksm=k-s столбцов без запрета на пустоту. Число матриц n×mn\times m с одинаковыми суммами строк равно

B(m)=r=0m(mr)n,B(m)=\sum_{r=0}^{m}\binom{m}{r}^n,

потому что для данного rr строки независимы (каждая выбирает rr позиций из mm).

Тогда ответ

Ans=s=0k(1)s(ks)B(ks)=s=0k(1)s(ks)r=0ks(ksr)n\text{Ans}=\sum_{s=0}^{k}(-1)^s \binom{k}{s}\, B(k-s) =\sum_{s=0}^{k}(-1)^s \binom{k}{s}\sum_{r=0}^{k-s}\binom{k-s}{r}^n

по модулю 998244353998244353.

Остаётся посчитать биномиальные коэффициенты за O(1)O(1) через факториалы, а суммы — за O(k2logn)O(k^2\log n).


Код (C++17)

cpp
#include <bits/stdc++.h> using namespace std; const long long MOD = 998244353; long long mod_pow(long long a, long long e) { long long r = 1 % MOD; a %= MOD; while (e > 0) { if (e & 1) r = (r * a) % MOD; a = (a * a) % MOD; e >>= 1; } return r; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, k; if (!(cin >> n >> k)) return 0; // factorials up to k vector<long long> fact(k + 1), invfact(k + 1); fact[0] = 1; for (int i = 1; i <= k; ++i) fact[i] = fact[i - 1] * i % MOD; invfact[k] = mod_pow(fact[k], MOD - 2); for (int i = k; i > 0; --i) invfact[i - 1] = invfact[i] * i % MOD; auto C = [&](int n_, int r_) -> long long { if (r_ < 0 || r_ > n_) return 0LL; return fact[n_] * invfact[r_] % MOD * invfact[n_ - r_] % MOD; }; // Precompute B[m] = sum_{r=0}^m C(m,r)^n for m=0..k vector<long long> B(k + 1, 0); for (int m = 0; m <= k; ++m) { long long s = 0; for (int r = 0; r <= m; ++r) { long long comb = C(m, r); s += mod_pow(comb, n); if (s >= MOD) s -= MOD; } B[m] = s; } long long ans = 0; for (int s = 0; s <= k; ++s) { int m = k - s; long long term = C(k, s) * B[m] % MOD; if (s % 2 == 0) { ans += term; } else { ans -= term; } ans %= MOD; } if (ans < 0) ans += MOD; cout << ans % MOD << '\n'; return 0; }

Сложность: O(k2logn)O(k^2\log n) по времени (для k3000k\le 3000 нормально) и O(k)O(k) по памяти.

Compartir este Q&A