#include <iostream>
#include <vector>
std::vector<std::pair<int, int>> factorize(int n) {
std::vector<std::pair<int, int>> factors;
for (int i = 2; static_cast<long long>(i) * i <= n; ++i) {
if (n % i == 0) {
int t = 0;
for (; n % i == 0; n /= i)
++t;
factors.emplace_back(i, t);
}
}
if (n > 1)
factors.emplace_back(n, 1);
return factors;
}
constexpr int power(int base, long long exp) {
int res = 1;
for (; exp > 0; base *= base, exp /= 2)
if (exp % 2 == 1)
res *= base;
return res;
}
constexpr int power(int base, long long exp, int mod) {
int res = 1 % mod;
for (; exp > 0; base = static_cast<long long>(base) * base % mod, exp /= 2)
if (exp % 2 == 1)
res = static_cast<long long>(res) * base % mod;
return res;
}
int inverse(int a, int m) {
int g = m, r = a, x = 0, y = 1;
while (r != 0) {
int q = g / r;
g %= r;
std::swap(g, r);
x -= q * y;
std::swap(x, y);
}
return x < 0 ? x + m : x;
}
int solveModuloEquations(const std::vector<std::pair<int, int>> &e) {
int m = 1;
for (std::size_t i = 0; i < e.size(); ++i)
m *= e[i].first;
int res = 0;
for (std::size_t i = 0; i < e.size(); ++i) {
int p = e[i].first;
res = (res + static_cast<long long>(e[i].second) * (m / p) * inverse(m / p, p)) % m;
}
return res;
}
class Binomial {
const int mod;
private:
const std::vector<std::pair<int, int>> factors;
std::vector<int> pk;
std::vector<std::vector<int>> prod;
static constexpr long long exponent(long long n, int p) {
long long res = 0;
for (n /= p; n > 0; n /= p)
res += n;
return res;
}
int product(long long n, std::size_t i) {
int res = 1;
int p = factors[i].first;
for (; n > 0; n /= p)
res = static_cast<long long>(res) * power(prod[i].back(), n / pk[i],
pk[i]) % pk[i] * prod[i][n % pk[i]] % pk[i];
return res;
}
public:
Binomial(int mod) : mod(mod), factors(factorize(mod)) {
pk.resize(factors.size());
prod.resize(factors.size());
for (std::size_t i = 0; i < factors.size(); ++i) {
int p = factors[i].first;
int k = factors[i].second;
pk[i] = power(p, k);
prod[i].resize(pk[i]);
prod[i][0] = 1;
for (int j = 1; j < pk[i]; ++j) {
if (j % p == 0) {
prod[i][j] = prod[i][j - 1];
} else {
prod[i][j] = static_cast<long long>(prod[i][j - 1]) * j % pk[i];
}
}
}
}
int operator()(long long n, long long m) {
if (n < m)
return 0;
std::vector<std::pair<int, int>> ans(factors.size());
for (std::size_t i = 0; i < factors.size(); ++i) {
int p = factors[i].first;
int k = factors[i].second;
int e = exponent(n, p) - exponent(m, p) - exponent(n - m, p);
if (e >= k) {
ans[i] = std::make_pair(pk[i], 0);
} else {
int pn = product(n, i);
int pm = product(m, i);
int pd = product(n - m, i);
int res = static_cast<long long>(pn) * inverse(pm, pk[i]) % pk[i] * inverse(pd, pk[i]) % pk[i] * power(p,
e) % pk[i];
ans[i] = std::make_pair(pk[i], res);
}
}
return solveModuloEquations(ans);
}
};
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int p;
std::cin >> p;
Binomial binom(p);
int n, m;
std::cin >> n >> m;
int sum = 0;
int res = 1;
for (int i = 0; i < m; ++i) {
int a;
std::cin >> a;
sum += a;
res = 1ll * res * binom(sum, a) % p;
}
if (sum > n) {
std::cout << "Impossible\n";
return 0;
}
res = 1ll * res * binom(n, sum) % p;
std::cout << res << "\n";
return 0;
}
一本通1659:礼物
最新推荐文章于 2024-09-04 21:39:45 发布