Submission #841086

#TimeUsernameProblemLanguageResultExecution timeMemory
841086peijarAmusement Park (CEOI19_amusementpark)C++17
42 / 100
412 ms1048576 KiB
#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 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<set<int>> adj(n); vector<int> bitAdj(n); for (int i = 0; i < m; ++i) { int u, v; cin >> u >> v; --u, --v; adj[u].insert(v); bitAdj[u] |= 1 << v; bitAdj[v] |= 1 << u; } auto toVector = [&](int msk) { vector<int> ret; for (int i = 0; i < n; ++i) if ((1 << i) & msk) ret.push_back(i + 1); return ret; }; vector<vector<Mint>> dpBack(1 << n, vector<Mint>(1 << n)); vector<vector<Mint>> dpForward(1 << n, vector<Mint>(1 << n)); dpBack[0][0] = 1; for (int added = 0; added < (1 << n); ++added) { int complement = (1 << n) - 1 - added; int bad = complement; while (true) { for (int nxt = 0; nxt < n; ++nxt) if (!((1 << nxt) & added) and !((1 << nxt) & bad)) { int nxtBad = bad & (bad ^ bitAdj[nxt]); for (int u = 0; u < nxt; ++u) if (!((1 << u) & added)) if (!((1 << u) & bitAdj[nxt])) nxtBad |= 1 << u; dpBack[added ^ (1 << nxt)][nxtBad] += dpBack[added][bad]; } if (!bad) break; bad = (bad - 1) & complement; } } dpForward[(1 << n) - 1][0] = 1; for (int added = (1 << n) - 2; added >= 0; --added) { int complement = (1 << n) - 1 - added; int bad = complement; while (true) { for (int nxt = 0; nxt < n; ++nxt) if (!((1 << nxt) & added) and !((1 << nxt) & bad)) { int nxtBad = bad & (bad ^ bitAdj[nxt]); for (int u = 0; u < nxt; ++u) if (!((1 << u) & added)) if (!((1 << u) & bitAdj[nxt])) nxtBad |= 1 << u; dpForward[added][bad] += dpForward[added ^ (1 << nxt)][nxtBad]; } if (!bad) break; bad = (bad - 1) & complement; } } Mint sol = 0; for (int added = 0; added < (1 << n); ++added) { int complement = (1 << n) - 1 - added; int bad = complement; while (true) { for (int nxt = 0; nxt < n; ++nxt) if (!((1 << nxt) & added) and !((1 << nxt) & bad)) { int nxtBad = bad & (bad ^ bitAdj[nxt]); for (int u = 0; u < nxt; ++u) if (!((1 << u) & added)) if (!((1 << u) & bitAdj[nxt])) nxtBad |= 1 << u; Mint cnt = dpForward[added ^ (1 << nxt)][nxtBad] * dpBack[added][bad]; int cntFlip = 0; for (int i = 0; i < n; ++i) if ((1 << i) & added) if (adj[nxt].count(i)) cntFlip++; sol += cnt * cntFlip; } if (!bad) break; bad = (bad - 1) & complement; } } Mint sumCost = 0; for (int msk = 1; msk < (1 << n); ++msk) for (int der = 0; der < n; ++der) if ((1 << der) & msk) { for (int nxt = 0; nxt < n; ++nxt) if (!((1 << nxt) & msk)) { if (nxt < der and !adj[der].count(nxt) and !adj[nxt].count(der)) continue; Mint cnt = dpForward[nxt][msk | (1 << nxt)] * dpBack[der][msk]; int toFlip = 0; for (int u = 0; u < n; ++u) if ((1 << u) & msk) if (adj[nxt].count(u)) toFlip++; sumCost += toFlip * cnt; } } cout << sol << endl; }

Compilation message (stderr)

amusementpark.cpp: In function 'int main()':
amusementpark.cpp:140:8: warning: variable 'toVector' set but not used [-Wunused-but-set-variable]
  140 |   auto toVector = [&](int msk) {
      |        ^~~~~~~~
#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...