結果
問題 | No.174 カードゲーム(Hard) |
ユーザー | keijak |
提出日時 | 2022-11-15 07:33:56 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 253 ms / 2,000 ms |
コード長 | 6,294 bytes |
コンパイル時間 | 2,312 ms |
コンパイル使用メモリ | 214,552 KB |
実行使用メモリ | 36,328 KB |
最終ジャッジ日時 | 2024-09-16 08:35:05 |
合計ジャッジ時間 | 4,991 ms |
ジャッジサーバーID (参考情報) |
judge6 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 251 ms
36,328 KB |
testcase_03 | AC | 253 ms
36,148 KB |
testcase_04 | AC | 251 ms
36,152 KB |
testcase_05 | AC | 251 ms
36,092 KB |
testcase_06 | AC | 251 ms
36,084 KB |
testcase_07 | AC | 253 ms
36,316 KB |
testcase_08 | AC | 251 ms
36,252 KB |
testcase_09 | AC | 250 ms
36,088 KB |
testcase_10 | AC | 2 ms
6,940 KB |
testcase_11 | AC | 2 ms
6,940 KB |
ソースコード
// #define NDEBUG #include <bits/stdc++.h> #define REP_(i, a_, b_, a, b, ...) for (int i = (a), END_##i = (b); i < END_##i; ++i) #define REP(i, ...) REP_(i, __VA_ARGS__, __VA_ARGS__, 0, __VA_ARGS__) #define ALL(x) std::begin(x), std::end(x) using Int = long long; using Uint = unsigned long long; using Real = long double; template<typename T, typename U> inline bool chmax(T &a, U b) { return a < b and ((a = b), true); } template<typename T, typename U> inline bool chmin(T &a, U b) { return a > b and ((a = b), true); } template<typename T> constexpr T kBig = std::numeric_limits<T>::max() / 2; #if __cplusplus < 202002L template<typename T> inline int ssize(const T &a) { return (int) a.size(); } #endif template<size_t BufSize> class InputReader { public: void skip() { [[maybe_unused]] static const bool lazy_init = [this]() { const size_t len = fread(buf_, 1, sizeof(buf_) - 1, stdin); buf_[len] = '\0'; ptr_ = buf_; bufend_ = buf_ + len; return true; }(); while (isspace(*ptr_)) ++ptr_; } template<typename T> operator T() { T x; skip(); assert(not is_eof()); // Couldn't read reached the end of input. read_one(x); return x; } struct Sized { InputReader<BufSize> &reader; int n; template<typename T> operator T() const { T xs(n); for (auto &x: xs) { reader.skip(); assert(not reader.is_eof()); reader.read_one(x); } return xs; } }; Sized operator()(int n) { return {*this, n}; } bool is_eof() const { return ptr_ >= bufend_; } private: template<class T> std::enable_if_t<std::is_integral_v<T>> read_one(T &x) { [[maybe_unused]] int sign = 1; if constexpr (std::is_signed_v<T>) { sign = (*ptr_ == '-') ? (++ptr_, -1) : 1; } x = 0; while (isdigit(*ptr_)) x = x * 10 + (*ptr_++ & 0x0F); if constexpr (std::is_signed_v<T>) { x *= sign; } } template<class T> std::enable_if_t<std::is_floating_point_v<T>> read_one(T &x) { [[maybe_unused]] int sign = 1; if constexpr (std::is_signed_v<T>) { sign = (*ptr_ == '-') ? (++ptr_, -1) : 1; } x = 0; while (isdigit(*ptr_)) x = x * 10 + (*ptr_++ & 0x0F); if (*ptr_ == '.') { ++ptr_; for (T base = 0.1; isdigit(*ptr_); ++ptr_, base *= 0.1) { x += (*ptr_ & 0x0F) * base; } } if constexpr (std::is_signed_v<T>) { x *= sign; } } void read_one(std::string &s) { char *p0 = ptr_; while (not isspace(*ptr_)) ptr_++; s.assign(p0, ptr_); } void read_one(std::string_view &s) { const char *p0 = ptr_; while (not isspace(*ptr_)) ptr_++; s = std::string_view(p0, ptr_ - p0); } static inline char buf_[BufSize]; char *ptr_, *bufend_; }; InputReader<(1 << 26)> in; template<typename Container> std::ostream &out_seq(const Container &seq, const char *sep = " ", const char *ends = "\n", std::ostream &os = std::cout) { const auto itl = std::begin(seq), itr = std::end(seq); for (auto it = itl; it != itr; ++it) { if (it != itl) os << sep; os << *it; } return os << ends; } template<typename T> std::ostream &out_one(const T &x, char endc) { if constexpr (std::is_same<T, bool>::value) { return std::cout << (x ? "Yes" : "No") << endc; } else { return std::cout << x << endc; } } template<typename T> std::ostream &out(const T &x) { return out_one(x, '\n'); } template<typename T, typename... Ts> std::ostream &out(const T &head, Ts... tail) { return out_one(head, ' '), out(tail...); } void init_() { // std::ios::sync_with_stdio(false); // std::cin.tie(nullptr); std::cout << std::fixed << std::setprecision(18); } [[noreturn]] void exit_() { #ifdef MY_DEBUG in.skip(); assert(in.is_eof()); // Some input is left. #endif fflush(stdout), fflush(stderr); std::cout.flush(), std::cerr.flush(); std::_Exit(0); } #ifdef MY_DEBUG #include "debug_dump.hpp" #include "backward.hpp" backward::SignalHandling kSignalHandling; #else #define DUMP(...) #define test_case(...) #define cerr if(false)cerr #endif using namespace std; template<typename T> bool has_bit(const T &x, int i) { return (x >> i) & 1; } template<typename T, typename U = std::make_unsigned_t<T>> int popcount(T x) { if constexpr (std::is_same_v<U, unsigned>) { return __builtin_popcount(static_cast<U>(x)); } else if constexpr (std::is_same_v<U, unsigned long>) { return __builtin_popcountl(static_cast<U>(x)); } else if constexpr (std::is_same_v<U, unsigned long long>) { return __builtin_popcountll(static_cast<U>(x)); } assert(false); // unsupported type } int countr_zero(unsigned x) { if (x == 0) return std::numeric_limits<unsigned>::digits; return __builtin_ctz(x); } int countr_one(unsigned x) { x = ~x; if (x == 0) return std::numeric_limits<unsigned>::digits; return __builtin_ctz(x); } auto solve() { const int n = in; const Real Pa = in, Pb = in; vector<int> A = in(n), B = in(n); sort(ALL(A)); sort(ALL(B)); const int kFull = (1 << n) - 1; auto f = [&](Real P, vector<Real> &dp, vector<vector<Real>> &H) { dp[0] = 1.0; REP(bits, kFull) { int pc = popcount(bits); Real cur = dp[bits]; if (cur == 0.0) continue; int smallest = countr_one(bits); if (pc + 1 == n) { dp[kFull] += cur; H[pc][smallest] += cur; continue; } dp[bits | (1 << smallest)] += cur * P; H[pc][smallest] += cur * P; if (n - (pc + 1) == 0) continue; Real R = (1.0 - P) / Real(n - (pc + 1)); for (int i = smallest + 1; i < n; ++i) { if (has_bit(bits, i)) continue; dp[bits | (1 << i)] += cur * R; H[pc][i] += cur * R; } } }; auto dpa = vector(1 << n, Real(0.0)); auto dpb = vector(1 << n, Real(0.0)); auto Ha = vector(n + 1, vector(n, Real(0.0))); auto Hb = vector(n + 1, vector(n, Real(0.0))); f(Pa, dpa, Ha); f(Pb, dpb, Hb); Real ans = 0; REP(i, n) { REP(x, n) { REP(y, n) { if (A[x] > B[y]) { ans += (A[x] + B[y]) * Ha[i][x] * Hb[i][y]; } } } } out(ans); } int main() { init_(); const int T = 1;//in; REP(t, T) { test_case(t, T); (solve()); } exit_(); }