結果
| 問題 | No.174 カードゲーム(Hard) |
| コンテスト | |
| ユーザー |
keijak
|
| 提出日時 | 2022-11-15 07:33:56 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 247 ms / 2,000 ms |
| コード長 | 6,294 bytes |
| コンパイル時間 | 2,106 ms |
| コンパイル使用メモリ | 209,388 KB |
| 最終ジャッジ日時 | 2025-02-08 20:23:01 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 12 |
ソースコード
// #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_();
}
keijak