QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#617804#7662. Kaldorian KnightsSkyEyeControllerWA 132ms65460kbC++2314.9kb2024-10-06 17:11:182024-10-06 17:11:20

Judging History

This is the latest submission verdict.

  • [2024-10-06 17:11:20]
  • Judged
  • Verdict: WA
  • Time: 132ms
  • Memory: 65460kb
  • [2024-10-06 17:11:18]
  • Submitted

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'