結果
問題 | No.1001 注文の多い順列 |
ユーザー | uenoku |
提出日時 | 2020-04-27 17:19:43 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 99 ms / 2,000 ms |
コード長 | 5,833 bytes |
コンパイル時間 | 1,984 ms |
コンパイル使用メモリ | 177,648 KB |
実行使用メモリ | 40,064 KB |
最終ジャッジ日時 | 2024-11-21 23:47:31 |
合計ジャッジ時間 | 4,860 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 27 ms
39,912 KB |
testcase_01 | AC | 26 ms
39,872 KB |
testcase_02 | AC | 27 ms
39,740 KB |
testcase_03 | AC | 27 ms
39,936 KB |
testcase_04 | AC | 27 ms
39,936 KB |
testcase_05 | AC | 27 ms
39,808 KB |
testcase_06 | AC | 27 ms
39,892 KB |
testcase_07 | AC | 27 ms
39,876 KB |
testcase_08 | AC | 27 ms
39,928 KB |
testcase_09 | AC | 26 ms
39,936 KB |
testcase_10 | AC | 27 ms
39,936 KB |
testcase_11 | AC | 27 ms
39,936 KB |
testcase_12 | AC | 28 ms
39,936 KB |
testcase_13 | AC | 28 ms
39,936 KB |
testcase_14 | AC | 28 ms
39,956 KB |
testcase_15 | AC | 28 ms
39,940 KB |
testcase_16 | AC | 27 ms
39,860 KB |
testcase_17 | AC | 27 ms
39,924 KB |
testcase_18 | AC | 61 ms
39,936 KB |
testcase_19 | AC | 58 ms
39,936 KB |
testcase_20 | AC | 46 ms
39,928 KB |
testcase_21 | AC | 45 ms
39,936 KB |
testcase_22 | AC | 67 ms
39,936 KB |
testcase_23 | AC | 67 ms
40,020 KB |
testcase_24 | AC | 69 ms
39,936 KB |
testcase_25 | AC | 68 ms
39,868 KB |
testcase_26 | AC | 97 ms
40,064 KB |
testcase_27 | AC | 98 ms
39,936 KB |
testcase_28 | AC | 99 ms
39,808 KB |
testcase_29 | AC | 48 ms
39,936 KB |
testcase_30 | AC | 48 ms
39,936 KB |
testcase_31 | AC | 47 ms
39,936 KB |
testcase_32 | AC | 41 ms
39,936 KB |
testcase_33 | AC | 89 ms
39,924 KB |
ソースコード
#include <bits/stdc++.h> #define rep(i, n) for (lli i = 0; i < (n); i++) #define rrep(i, n) for (lli i = (n)-1; i >= 0; i--) using namespace std; using lli = long long int; void YESNO(bool), YesNo(bool); template <class T1, class T2> bool chmin(T1 &l, const T2 &r); template <class T1, class T2> bool chmax(T1 &l, const T2 &r); template <signed M, unsigned T> struct mod_int { constexpr static signed MODULO = M; constexpr static unsigned TABLE_SIZE = T; signed x; mod_int() : x(0) {} mod_int(long long y) : x(static_cast<signed>(y >= 0 ? y % MODULO : MODULO - (-y) % MODULO)) {} mod_int(int y) : x(y >= 0 ? y % MODULO : MODULO - (-y) % MODULO) {} mod_int &operator+=(const mod_int &rhs) { if ((x += rhs.x) >= MODULO) x -= MODULO; return *this; } mod_int &operator-=(const mod_int &rhs) { if ((x += MODULO - rhs.x) >= MODULO) x -= MODULO; return *this; } mod_int &operator*=(const mod_int &rhs) { x = static_cast<signed>(1LL * x * rhs.x % MODULO); return *this; } mod_int &operator/=(const mod_int &rhs) { x = static_cast<signed>((1LL * x * rhs.inv().x) % MODULO); return *this; } mod_int operator-() const { return mod_int(-x); } mod_int operator+(const mod_int &rhs) const { return mod_int(*this) += rhs; } mod_int operator-(const mod_int &rhs) const { return mod_int(*this) -= rhs; } mod_int operator*(const mod_int &rhs) const { return mod_int(*this) *= rhs; } mod_int operator/(const mod_int &rhs) const { return mod_int(*this) /= rhs; } bool operator<(const mod_int &rhs) const { return x < rhs.x; } mod_int inv() const { assert(x != 0); if (x <= static_cast<signed>(TABLE_SIZE)) { if (_inv[1].x == 0) prepare(); return _inv[x]; } else { signed a = x, b = MODULO, u = 1, v = 0, t; while (b) { t = a / b; a -= t * b; std::swap(a, b); u -= t * v; std::swap(u, v); } return mod_int(u); } } mod_int pow(long long t) const { assert(!(x == 0 && t == 0)); mod_int e = *this, res = mod_int(1); for (; t; e *= e, t >>= 1) if (t & 1) res *= e; return res; } mod_int fact() { if (_fact[0].x == 0) prepare(); return _fact[x]; } mod_int inv_fact() { if (_fact[0].x == 0) prepare(); return _inv_fact[x]; } mod_int choose(mod_int y) { assert(y.x <= x); return this->fact() * y.inv_fact() * mod_int(x - y.x).inv_fact(); } static mod_int _inv[TABLE_SIZE + 1]; static mod_int _fact[TABLE_SIZE + 1]; static mod_int _inv_fact[TABLE_SIZE + 1]; static void prepare() { _inv[1] = 1; for (int i = 2; i <= (int)TABLE_SIZE; ++i) { _inv[i] = 1LL * _inv[MODULO % i].x * (MODULO - MODULO / i) % MODULO; } _fact[0] = 1; for (unsigned i = 1; i <= TABLE_SIZE; ++i) { _fact[i] = _fact[i - 1] * int(i); } _inv_fact[TABLE_SIZE] = _fact[TABLE_SIZE].inv(); for (int i = (int)TABLE_SIZE - 1; i >= 0; --i) { _inv_fact[i] = _inv_fact[i + 1] * (i + 1); } } }; template <int M, unsigned F> std::ostream &operator<<(std::ostream &os, const mod_int<M, F> &rhs) { return os << rhs.x; } template <int M, unsigned F> std::istream &operator>>(std::istream &is, mod_int<M, F> &rhs) { long long s; is >> s; rhs = mod_int<M, F>(s); return is; } template <int M, unsigned F> mod_int<M, F> mod_int<M, F>::_inv[TABLE_SIZE + 1]; template <int M, unsigned F> mod_int<M, F> mod_int<M, F>::_fact[TABLE_SIZE + 1]; template <int M, unsigned F> mod_int<M, F> mod_int<M, F>::_inv_fact[TABLE_SIZE + 1]; template <int M, unsigned F> bool operator==(const mod_int<M, F> &lhs, const mod_int<M, F> &rhs) { return lhs.x == rhs.x; } template <int M, unsigned F> bool operator!=(const mod_int<M, F> &lhs, const mod_int<M, F> &rhs) { return !(lhs == rhs); } const int MF = 100005; //割り算しないなら const int MOD = 1000000007; using mint = mod_int<MOD, MF>; mint binom(int n, int r) { return (r < 0 || r > n || n < 0) ? 0 : mint(n).choose(r); } mint fact(int n) { return mint(n).fact(); } mint inv_fact(int n) { return mint(n).inv_fact(); } mint dp[3005][3005]; // dp[i][j] := type 0の条件をi個満たしている, type 1の条件をj個満たしている int main() { int n; cin >> n; vector<int> t(n), X(n); vector<int> u[2]; rep(i, n) cin >> t[i] >> X[i]; rep(i, n) u[t[i]].push_back(X[i] - 1); rep(i, 2) sort(u[i].begin(), u[i].end()); dp[0][0] = 1; rep(i, n) { // insert i vector<int> v[2]; for (auto s : u[0]) if (i <= s) v[0].push_back(s); for (auto s : u[1]) if (i >= s) v[1].push_back(s); rep(a, v[1].size() + 1) { if (i < a) continue; lli b = i - a; // a個条件を満たしている, b個条件を満たしていいる // type 0:v[0].size()の中からまだ使われてないものを使う sz-a // type 1:使えるもののうちあんまりX[i]が大きいのを使ってしまうとあとから困るかも // 選択肢は? のこりu[1].size()-(b+1)個おく必要があるが dp[a + 1][b] += dp[a][b] * (mint((lli)v[1].size() - a)); if (b < u[0].size()) dp[a][b + 1] += dp[a][b] * (mint((lli)v[0].size()) - mint((lli)u[0].size() - (b + 1))); } } mint ret = 0; rep(i, n + 1) ret += dp[n - i][i]; cout << ret << endl; } // -- lib void YESNO(bool b) { cout << (b ? "YES" : "NO") << endl; } void YesNo(bool b) { cout << (b ? "Yes" : "No") << endl; } template <class T1, class T2> bool chmin(T1 &l, const T2 &r) { return (l > r) ? (l = r, true) : false; } template <class T1, class T2> bool chmax(T1 &l, const T2 &r) { return (l < r) ? (l = r, true) : false; }