Submission #841142

#TimeUsernameProblemLanguageResultExecution timeMemory
841142peijarAmusement Park (CEOI19_amusementpark)C++17
100 / 100
2023 ms608436 KiB
#include <bits/extc++.h> /** keep-include */ #include <bits/stdc++.h> #define int long long using namespace std; string to_string(string s) { return s; } template <typename T> string to_string(T v) { bool first = true; string res = "["; for (const auto &x : v) { if (!first) res += ", "; first = false; res += to_string(x); } res += "]"; return res; } void dbg_out() { cout << endl; } template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << to_string(H); dbg_out(T...); } #ifdef DEBUG #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__) #else #define dbg(...) #endif using ll = int; // To use most bits rather than just the lowest ones: struct chash { // large odd number for C const uint64_t C = ll(4e18 * acos(0)) | 71; ll operator()(ll x) const { return __builtin_bswap64(x * C); } }; using hash_table = __gnu_pbds::gp_hash_table<int, int, chash>; template <const int32_t MOD> struct ModInt { int32_t x; ModInt() : x(0) {} ModInt(long long u) : x(u % MOD) { if (x < 0) x += MOD; } friend bool operator==(const ModInt &a, const ModInt &b) { return a.x == b.x; } friend bool operator!=(const ModInt &a, const ModInt &b) { return a.x != b.x; } friend bool operator<(const ModInt &a, const ModInt &b) { return a.x < b.x; } friend bool operator>(const ModInt &a, const ModInt &b) { return a.x > b.x; } friend bool operator<=(const ModInt &a, const ModInt &b) { return a.x <= b.x; } friend bool operator>=(const ModInt &a, const ModInt &b) { return a.x >= b.x; } static ModInt sign(long long k) { return ((k & 1) ? ModInt(MOD - 1) : ModInt(1)); } ModInt &operator+=(const ModInt &m) { x += m.x; if (x >= MOD) x -= MOD; return *this; } ModInt &operator-=(const ModInt &m) { x -= m.x; if (x < 0LL) x += MOD; return *this; } ModInt &operator*=(const ModInt &m) { x = (1LL * x * m.x) % MOD; return *this; } friend ModInt operator-(const ModInt &a) { ModInt res(a); if (res.x) res.x = MOD - res.x; return res; } friend ModInt operator+(const ModInt &a, const ModInt &b) { return ModInt(a) += ModInt(b); } friend ModInt operator-(const ModInt &a, const ModInt &b) { return ModInt(a) -= ModInt(b); } friend ModInt operator*(const ModInt &a, const ModInt &b) { return ModInt(a) *= ModInt(b); } static long long fp(long long u, long long k) { long long res = 1LL; while (k > 0LL) { if (k & 1LL) res = (res * u) % MOD; u = (u * u) % MOD; k /= 2LL; } return res; } static constexpr int mod() { return MOD; } ModInt fastpow(long long k) { return ModInt(fp(x, k)); } ModInt inv() { assert(x); return ModInt(fp(x, MOD - 2)); } ModInt &operator/=(const ModInt &m) { return *this *= ModInt(m).inv(); } friend ModInt operator/(const ModInt &a, const ModInt &b) { return ModInt(a) *= ModInt(b).inv(); } friend ostream &operator<<(ostream &out, const ModInt &a) { return out << a.x; } friend istream &operator>>(istream &in, ModInt &a) { return in >> a.x; } friend string to_string(ModInt u) { return to_string(u.x); } }; // const int MOD = 1e9 + 7; const int MOD = 998244353; using Mint = ModInt<MOD>; signed main(void) { ios_base::sync_with_stdio(false); cin.tie(0); int n, m; cin >> n >> m; vector<int> adj(n); vector<int> bitAdj(n); for (int i = 0; i < m; ++i) { int u, v; cin >> u >> v; --u, --v; adj[u] |= 1 << v; bitAdj[u] |= 1 << v; bitAdj[v] |= 1 << u; } vector<int> areBad(n); for (int u = 0; u < n; ++u) for (int v = 0; v < u; ++v) if (!((1 << v) & bitAdj[u])) areBad[u] |= 1 << v; vector<vector<tuple<int, Mint, Mint>>> interesting(1 << n); interesting[0].emplace_back(0, 1, 0); for (int added = 0; added < (1 << n); ++added) { sort(interesting[added].begin(), interesting[added].end()); vector<tuple<int, Mint, Mint>> compressed; for (auto [bad, ways, sum] : interesting[added]) { if (compressed.empty() or get<0>(compressed.back()) != bad) compressed.emplace_back(bad, 0, 0); auto &[b, w, s] = compressed.back(); w += ways; s += sum; } int complement = (1 << n) - 1 - added; for (auto [bad, ways, sum] : compressed) { for (int nxt = 0; nxt < n; ++nxt) if (!((1 << nxt) & added) and !((1 << nxt) & bad)) { int nxtBad = bad & (bad ^ bitAdj[nxt]); nxtBad |= areBad[nxt] & complement; int cntFlip = __builtin_popcount(adj[nxt] & added); interesting[added ^ (1 << nxt)].emplace_back(nxtBad, ways, cntFlip * ways + sum); } } } Mint sol = 0; for (auto [bad, ways, sum] : interesting[(1 << n) - 1]) { assert(!bad); sol += sum; } cout << sol << endl; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...