1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| #include <bits/stdc++.h>
using u64 = uint64_t;
const int kMaxN = 2e5 + 5, kMod = 1e9 + 7;
int n, m, c, cnte, cnt[2]; int u[kMaxN], v[kMaxN], dep[kMaxN], low[kMaxN]; u64 hs[kMaxN]; bool ont[kMaxN]; std::vector<std::pair<int, int>> G[kMaxN]; std::unordered_map<u64, int> mp; std::mt19937_64 rnd(std::random_device{}());
int qpow(int bs, int64_t idx = kMod - 2) { if (idx < 0) return 0; int ret = 1; for (; idx; idx >>= 1, bs = (int64_t)bs * bs % kMod) if (idx & 1) ret = (int64_t)ret * bs % kMod; return ret; }
inline int add(int x, int y) { return (x + y >= kMod ? x + y - kMod : x + y); } inline int sub(int x, int y) { return (x >= y ? x - y : x - y + kMod); } inline void inc(int &x, int y) { (x += y) >= kMod ? x -= kMod : x; } inline void dec(int &x, int y) { (x -= y) < 0 ? x += kMod : x; }
void clear() { mp.clear(); for (int i = 1; i <= n; ++i) dep[i] = hs[i] = low[i] = 0, G[i].clear(); for (int i = 1; i <= m; ++i) ont[i] = 0; }
void dfs1(int u, int fa) { low[u] = dep[u]; for (auto [v, id] : G[u]) { if (id == fa) continue; if (!dep[v]) { ont[id] = 1, dep[v] = dep[u] + 1, dfs1(v, id); low[u] = std::min(low[u], low[v]); if (low[v] <= dep[u]) ++cnte; } else if (dep[u] <= dep[v]) { u64 val = rnd(); ++mp[val]; hs[u] ^= val, hs[v] ^= val, ++cnte; } low[u] = std::min(low[u], dep[v]); } }
void dfs2(int u, int fa) { for (auto [v, id] : G[u]) { if (id == fa || !ont[id]) continue; dfs2(v, id); hs[u] ^= hs[v]; } if (low[u] < dep[u]) inc(cnt[1], 2 * (mp[hs[u]]++)); }
void dickdreamer() { clear(); for (int i = 1; i <= m; ++i) { std::cin >> u[i] >> v[i]; G[u[i]].emplace_back(v[i], i); if (u[i] != v[i]) G[v[i]].emplace_back(u[i], i); } c = cnte = cnt[0] = cnt[1] = 0; for (int i = 1; i <= n; ++i) { if (!dep[i]) { ++c, dep[i] = 1, dfs1(i, 0), dfs2(i, 0); } } int tot = 1ll * cnte * (cnte - 1) % kMod; cnt[0] = sub(tot, cnt[1]); int ans = 0; inc(ans, 1ll * cnt[0] * qpow(2, m - 2 - n + c) % kMod); inc(ans, 1ll * cnt[1] * qpow(2, m - 2 - n + c + 1) % kMod); inc(ans, 1ll * cnte * qpow(2, m - 1 - n + c) % kMod); std::cout << ans << '\n'; }
int32_t main() { #ifdef ORZXKR freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0); int T = 1; while (std::cin >> n >> m) dickdreamer(); return 0; }
|