记录编号 577856 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [USACO20Dec Platinum]Sleeping Cows 最终得分 100
用户昵称 Gravatarlihaoze 是否通过 通过
代码语言 C++ 运行时间 0.323 s
提交时间 2022-11-24 20:55:58 内存使用 0.00 MiB
显示代码纯文本
#include "bits/stdc++.h"

using i64 = long long;

constexpr int P = 1e9 + 7;
 
int norm(int x) {
    if (x < 0) 
        x += P;
    if (x >= P)
        x -= P;
    return x;
}
 
template <class T>
T power(T a, i64 b) {
    T res = 1;
    for (; b; b /= 2, a *= a)
        if (b % 2)
            res *= a;
    return res;
}
 
struct Z {
    int x;
    Z (int x = 0) : x(norm(x)) { }
    Z (i64 x) : x(norm(x % P)) { }
    int val() const {
        return x;
    }
    Z inv() const {
        assert(x != 0);
        return power(*this, P - 2);
    }
    Z & operator *= (const Z &rhs) {
        x = i64(x) * rhs.x % P;
        return *this;
    }
    Z & operator += (const Z &rhs) {
        x = norm(x + rhs.x);
        return *this;
    }
    Z & operator -= (const Z &rhs) {
        x = norm(x - rhs.x);
        return *this;
    }
    Z & operator /= (const Z &rhs) {
        return *this *= rhs.inv();
    }
    friend Z operator * (const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res *= rhs;
        return res;
    }
    friend Z operator + (const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res += rhs;
        return res;
    }
    friend Z operator - (const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res -= rhs;
        return res;
    }
    friend Z operator / (const Z &lhs, const Z &rhs) {
        Z res = lhs;
        res /= rhs;
        return res;
    }
    friend std::istream & operator >> (std::istream &is, Z &a) {
        i64 v;
        is >> v;
        a = Z(v);
        return is;
    }
    friend std::ostream & operator << (std::ostream &os, const Z &a) {
        return os << a.val();
    }
};

using PII = std::pair<int, int>;

const int N = 6010;
int n;
Z f[2][N][2];
PII a[N];

int main() {
    freopen("usaco_20Dec_sleep.in", "r", stdin); 
    freopen("usaco_20Dec_sleep.out", "w", stdout);
    
    std::cin >> n;

    for (int i = 1; i <= n; ++ i) {
        auto& [x, y] = a[i];
        std::cin >> x, y = 0;
    }
    for (int i = n + 1; i <= 2 * n; ++ i) {
        auto& [x, y] = a[i];
        std::cin >> x, y = 1;
    }

    std::sort(a + 1, a + 1 + n * 2);

    f[0][0][1] = 1;

    for (int i = 1; i <= 2 * n; ++ i) {
        auto [_, x] = a[i];

        memset(f[i & 1], 0, sizeof f[i & 1]);

        if (x == 0) {
            for (int j = 0; j <= n; ++ j) {
                if (j) f[i & 1][j][0] += f[(i + 1) & 1][j - 1][0];
                if (j) f[i & 1][j][1] += f[(i + 1) & 1][j - 1][1];
                f[i & 1][j][0] += f[(i + 1) & 1][j][0] + f[(i + 1) & 1][j][1];
            }
        } else {
            for (int j = 0; j <= n; ++ j) {
                f[i & 1][j][1] += f[(i + 1) & 1][j][1] + f[(i + 1) & 1][j + 1][1] * Z(j + 1);
                f[i & 1][j][0] += f[(i + 1) & 1][j + 1][0] * Z(j + 1);
            }
        }
    }

    std::cout << f[(n * 2) & 1][0][0] + f[(n * 2) & 1][0][1] << '\n';
    return 0;
}