QOJ.ac
QOJ
The 2nd Universal Cup Finals is coming! Check out our event page, schedule, and competition rules!
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#617804 | #7662. Kaldorian Knights | SkyEyeController | WA | 132ms | 65460kb | C++23 | 14.9kb | 2024-10-06 17:11:18 | 2024-10-06 17:11:20 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#ifndef __MODINT_H__
#define __MODINT_H__
#ifndef i64
#define i64 long long
#endif
#ifndef d64
#define d64 long double
#endif
#ifndef u64
#define u64 unsigned long long
#endif
#ifndef d32
#define d32 double
#endif
#include <bits/stdc++.h>
using namespace std;
namespace Modint
{
template <class T>
constexpr T power(T a, i64 b)
{
T res = 1;
for (; b; b /= 2, a *= a)
{
if (b % 2)
{
res *= a;
}
}
return res;
}
constexpr i64 mul(i64 a, i64 b, i64 p)
{
i64 res = a * b - (i64)(1.L * a * b / p) * p;
res %= p;
if (res < 0)
{
res += p;
}
return res;
}
/*
* @brief 模运算(i64),jiangly版本,支持动态模数改变
* @param P 模数,仅支持质数。如果选择动态定义模数,P=0,且必须调用setMod函数设置模数。默认为1e18+9
*/
template <i64 P>
struct MLong
{
i64 x;
constexpr MLong() : x{} {}
constexpr MLong(i64 x) : x{norm(x % getMod())} {}
static i64 Mod;
constexpr static i64 getMod()
{
if (P > 0)
{
return P;
}
else
{
return Mod;
}
}
constexpr static void setMod(i64 Mod_)
{
Mod = Mod_;
}
constexpr i64 norm(i64 x) const
{
if (x < 0)
{
x += getMod();
}
if (x >= getMod())
{
x -= getMod();
}
return x;
}
constexpr i64 val() const
{
return x;
}
explicit constexpr operator i64() const
{
return x;
}
constexpr MLong operator-() const
{
MLong res;
res.x = norm(getMod() - x);
return res;
}
constexpr MLong inv() const
{
assert(x != 0);
return power(*this, getMod() - 2);
}
constexpr MLong &operator*=(MLong rhs) &
{
x = mul(x, rhs.x, getMod());
return *this;
}
constexpr MLong &operator+=(MLong rhs) &
{
x = norm(x + rhs.x);
return *this;
}
constexpr MLong &operator-=(MLong rhs) &
{
x = norm(x - rhs.x);
return *this;
}
constexpr MLong &operator/=(MLong rhs) &
{
return *this *= rhs.inv();
}
friend constexpr MLong operator*(MLong lhs, MLong rhs)
{
MLong res = lhs;
res *= rhs;
return res;
}
friend constexpr MLong operator+(MLong lhs, MLong rhs)
{
MLong res = lhs;
res += rhs;
return res;
}
friend constexpr MLong operator-(MLong lhs, MLong rhs)
{
MLong res = lhs;
res -= rhs;
return res;
}
friend constexpr MLong operator/(MLong lhs, MLong rhs)
{
MLong res = lhs;
res /= rhs;
return res;
}
friend constexpr std::istream &operator>>(std::istream &is, MLong &a)
{
i64 v;
is >> v;
a = MLong(v);
return is;
}
friend constexpr std::ostream &operator<<(std::ostream &os, const MLong &a)
{
return os << a.val();
}
friend constexpr bool operator==(MLong lhs, MLong rhs)
{
return lhs.val() == rhs.val();
}
friend constexpr bool operator!=(MLong lhs, MLong rhs)
{
return lhs.val() != rhs.val();
}
};
template <>
i64 MLong<0LL>::Mod = (i64)(1E18) + 9;
/*template <i64 V, i64 P>
constexpr MLong<P> CInv = MLong<P>(V).inv();*/
/*
* @brief 模运算(int),jiangly版本,支持动态模数改变
* @param P 模数,仅支持质数。如果选择动态定义模数,P=0,且必须调用setMod函数设置模数。默认为998244353
*/
template <int P>
struct MInt
{
int x;
constexpr MInt() : x{} {}
constexpr MInt(i64 x) : x{norm(x % getMod())} {}
static int Mod;
constexpr static int getMod()
{
if (P > 0)
{
return P;
}
else
{
return Mod;
}
}
constexpr static void setMod(int Mod_)
{
Mod = Mod_;
}
constexpr int norm(int x) const
{
if (x < 0)
{
x += getMod();
}
if (x >= getMod())
{
x -= getMod();
}
return x;
}
constexpr int val() const
{
return x;
}
explicit constexpr operator int() const
{
return x;
}
constexpr MInt operator-() const
{
MInt res;
res.x = norm(getMod() - x);
return res;
}
constexpr MInt inv() const
{
assert(x != 0);
return power(*this, getMod() - 2);
}
constexpr MInt &operator*=(MInt rhs) &
{
x = 1LL * x * rhs.x % getMod();
return *this;
}
constexpr MInt &operator+=(MInt rhs) &
{
x = norm(x + rhs.x);
return *this;
}
constexpr MInt &operator-=(MInt rhs) &
{
x = norm(x - rhs.x);
return *this;
}
constexpr MInt &operator/=(MInt rhs) &
{
return *this *= rhs.inv();
}
friend constexpr MInt operator*(MInt lhs, MInt rhs)
{
MInt res = lhs;
res *= rhs;
return res;
}
friend constexpr MInt operator+(MInt lhs, MInt rhs)
{
MInt res = lhs;
res += rhs;
return res;
}
friend constexpr MInt operator-(MInt lhs, MInt rhs)
{
MInt res = lhs;
res -= rhs;
return res;
}
friend constexpr MInt operator/(MInt lhs, MInt rhs)
{
MInt res = lhs;
res /= rhs;
return res;
}
friend constexpr std::istream &operator>>(std::istream &is, MInt &a)
{
i64 v;
is >> v;
a = MInt(v);
return is;
}
friend constexpr std::ostream &operator<<(std::ostream &os, const MInt &a)
{
return os << a.val();
}
friend constexpr bool operator==(MInt lhs, MInt rhs)
{
return lhs.val() == rhs.val();
}
friend constexpr bool operator!=(MInt lhs, MInt rhs)
{
return lhs.val() != rhs.val();
}
};
template <>
int MInt<0>::Mod = 998244353;
// 逆元
template <int V, int P>
constexpr MInt<P> CInv = MInt<P>(V).inv();
/*
* @brief 模运算类,支持加减乘除取模取幂等操作,初始化时需要指定模数,不支持动态模数改变
* @param MOD 模数,一般取质数,部分合数情况下可能没有逆元。
* @note 支持负数取模,但是不支持负数取幂。话说,负数取幂是什么鬼?
* @note 支持输入输出流,可以直接使用cin和cout进行输入输出。
* @note 支持快速幂运算,可以使用quickpow(a,b)进行快速幂运算。
* @note 支持字符串转换,可以使用tostring(a)将a转换为字符串。
* @note 支持比较运算,可以使用==和<进行比较。
* @note 支持取模运算,可以使用a%b进行取模运算。
* @note 内置线性求逆元算法,可以使用linear_get_inv(a)获得1~n的逆元。
*/
template <int MOD>
struct modint
{
int val;
int mod_ = 0;
static int norm(const int &x) { return x < 0 ? x + MOD : x; }
static constexpr int get_mod() { return MOD; }
modint inv() const
{
assert(val);
int a = val, b = MOD, u = 1, v = 0, t;
while (b > 0)
t = a / b, swap(a -= t * b, b), swap(u -= t * v, v);
assert(b == 0);
return modint(u);
}
modint() : val(0) {}
modint(const int &m) : val(norm(m)) {}
modint(const long long &m) : val(norm(m % MOD)) {}
modint operator-() const { return modint(norm(-val)); }
bool operator==(const modint &o) { return val == o.val; }
bool operator<(const modint &o) { return val < o.val; }
modint &operator+=(const modint &o) { return val = (1ll * val + o.val) % MOD, *this; }
modint &operator-=(const modint &o) { return val = norm(1ll * val - o.val), *this; }
modint &operator*=(const modint &o) { return val = static_cast<int>(1ll * val * o.val % MOD), *this; }
modint &operator/=(const modint &o) { return *this *= o.inv(); }
modint &operator^=(const modint &o) { return val ^= o.val, *this; }
modint &operator>>=(const modint &o) { return val >>= o.val, *this; }
modint &operator<<=(const modint &o) { return val <<= o.val, *this; }
modint operator-(const modint &o) const { return modint(*this) -= o; }
modint operator+(const modint &o) const { return modint(*this) += o; }
modint operator*(const modint &o) const { return modint(*this) *= o; }
modint operator/(const modint &o) const { return modint(*this) /= o; }
modint operator^(const modint &o) const { return modint(*this) ^= o; }
modint operator>>(const modint &o) const { return modint(*this) >>= o; }
modint operator<<(const modint &o) const { return modint(*this) <<= o; }
friend std::istream &operator>>(std::istream &is, modint &a)
{
long long v;
return is >> v, a.val = norm(v % MOD), is;
}
friend std::ostream &operator<<(std::ostream &os, const modint &a) { return os << a.val; }
friend std::string tostring(const modint &a) { return std::to_string(a.val); }
friend modint quickpow(const modint &a, const int &b)
{
assert(b >= 0);
modint x = a, res = 1;
for (int p = b; p; x *= x, p >>= 1LL)
if (p & 1)
res *= x;
return res;
}
friend vector<modint> linear_get_inv(modint a)
{
int n = a.val;
vector<modint> inv(n + 1);
inv[1] = 1;
for (int i = 2; i <= n; i++)
inv[i] = modint(0) - modint(MOD / i) * inv[MOD % i];
return inv;
}
};
/*
* @brief 阶乘类,支持计算组合数,排列数等操作,复杂度O(n),不配套jiangly版本的模运算类
* @brief 小数据时需要组合数建议使用组合数表(杨辉三角),大数据时需要组合数建议使用Lucas定理
* @param MOD 模数,一般取质数,部分合数情况下可能没有逆元。
* @note 支持计算组合数,可以使用C(n,k)计算组合数。
* @note 支持计算排列数,可以使用A(n,k)计算排列数。
*/
template <int MOD>
struct fact
{
std::vector<modint<MOD>> fact, factinv;
const int n;
fact(const int &_n) : n(_n), fact(_n + 1, modint<MOD>(1)), factinv(_n + 1)
{
for (int i = 1; i <= n; ++i)
fact[i] = fact[i - 1] * i;
factinv[n] = fact[n].inv();
for (int i = n; i; --i)
factinv[i - 1] = factinv[i] * i;
}
modint<MOD> C(const int &n, const int &k)
{
if (n < 0 || k < 0 || n < k)
return 0;
return fact[n] * factinv[k] * factinv[n - k];
}
modint<MOD> A(const int &n, const int &k)
{
if (n < 0 || k < 0 || n < k)
return 0;
return fact[n] * factinv[n - k];
}
};
/*
* @brief 阶乘类(适配Jiangly模板),支持计算组合数,排列数等操作,复杂度O(n),配套jiangly版本的模运算类
* @brief 小数据时需要组合数建议使用组合数表(杨辉三角),大数据时需要组合数建议使用Lucas定理
* @param MOD 模数,一般取质数,部分合数情况下可能没有逆元。
* @note 支持计算组合数,可以使用C(n,k)计算组合数。
* @note 支持计算排列数,可以使用A(n,k)计算排列数。
*/
template <class T>
struct Fact
{
std::vector<T> fact, factinv;
const int n;
Fact(const int &_n) : n(_n), fact(_n + 1, 1), factinv(_n + 1)
{
for (int i = 1; i <= n; ++i)
fact[i] = fact[i - 1] * i;
factinv[n] = fact[n].inv();
for (int i = n; i; --i)
factinv[i - 1] = factinv[i] * i;
}
T C(const int &n, const int &k)
{
if (n < 0 || k < 0 || n < k)
return 0;
return fact[n] * factinv[k] * factinv[n - k];
}
T A(const int &n, const int &k)
{
if (n < 0 || k < 0 || n < k)
return 0;
return fact[n] * factinv[n - k];
}
};
};
#endif //__MODINT_H__
using namespace Modint;
using mint = MLong<1000000007>;
const int maxn = 4e6 + 9;
Fact<mint> f(maxn);
const int fur = 5010;
int family[fur], prefam[fur];
int main()
{
int n, h;
cin >> n >> h;
for (int i = 1; i <= n; i++)
{
cin >> family[i];
prefam[i] = prefam[i - 1] + family[i];
}
if (!h)
{
cout << f.A(n, n) << endl;
return 0;
}
mint cnt = f.A(prefam[h], prefam[h]) * f.A(n - prefam[h], n - prefam[h]);
for (int i = h - 1; i >= 1; i--)
{
mint res = f.A(prefam[i], prefam[i]);
mint tmp = f.A(n - prefam[i], n - prefam[i]) -
f.A(prefam[h] - prefam[i], prefam[h] - prefam[i]) * f.A(n - prefam[h], n - prefam[h]) -
f.A(prefam[i + 1] - prefam[i], prefam[i + 1] - prefam[i]) * f.A(n - prefam[i + 1], n - prefam[i + 1]) +
f.A(prefam[i + 1] - prefam[i], prefam[i + 1] - prefam[i]) * f.A(prefam[h] - prefam[i + 1], prefam[h] - prefam[i + 1]) * f.A(n - prefam[h], n - prefam[h]);
cnt += res * tmp;
}
mint ans = f.A(n, n) - cnt;
cout << ans << endl;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 127ms
memory: 65296kb
input:
3 0
output:
6
result:
ok single line: '6'
Test #2:
score: 0
Accepted
time: 129ms
memory: 65420kb
input:
4 1 3
output:
18
result:
ok single line: '18'
Test #3:
score: 0
Accepted
time: 131ms
memory: 65300kb
input:
4 2 2 1
output:
16
result:
ok single line: '16'
Test #4:
score: 0
Accepted
time: 127ms
memory: 65460kb
input:
10 1 10
output:
0
result:
ok single line: '0'
Test #5:
score: 0
Accepted
time: 131ms
memory: 65440kb
input:
10 10 1 1 1 1 1 1 1 1 1 1
output:
0
result:
ok single line: '0'
Test #6:
score: -100
Wrong Answer
time: 132ms
memory: 65364kb
input:
1357 7 56 173 21 103 96 149 38
output:
859755536
result:
wrong answer 1st lines differ - expected: '1000000006', found: '859755536'