BZOJ5473: 仙人掌

$d_i$ 表示 $i$ 的度数，那么每个点孤立的概率为 $\frac{1}{2^{d_i}}$

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;

namespace IO {
const int maxn(1 << 21 | 1);

char ibuf[maxn], *iS, *iT, c;
int f;

inline char Getc() {
return (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, maxn, stdin), (iS == iT ? EOF : *iS++)) : *iS++);
}

template <class Int> inline void In(Int &x) {
for (f = 1, c = Getc(); c < '0' || c > '9'; c = Getc()) f = c == '-' ? -1 : 1;
for (x = 0; c <= '9' && c >= '0'; c = Getc()) x = (x << 3) + (x << 1) + (c ^ 48);
x *= f;
}
}

using IO :: In;

const int maxn(1e6 + 5);
const int mod(1e9 + 7);

inline void Inc(int &x, const int y) {
x = x + y >= mod ? x + y - mod : x + y;
}

inline void Dec(int &x, const int y) {
x = x - y < 0 ? x - y + mod : x - y;
}

inline int Add(int x, const int y) {
return x + y >= mod ? x + y - mod : x + y;
}

inline int Sub(int x, const int y) {
return x - y < 0 ? x - y + mod : x - y;
}

inline int Pow(ll x, int y) {
ll ret = 1;
for (; y; y >>= 1, x = x * x % mod)
if (y & 1) ret = ret * x % mod;
return ret;
}

struct Edge {  int to, next;  };

int n, m, d[maxn], first[maxn], cnt, inv2[maxn << 1], fa[maxn], ans, vis[maxn], deep[maxn];
Edge edge[maxn << 2];

inline void AddEdge(int u, int v) {
edge[cnt] = (Edge){v, first[u]}, first[u] = cnt++, ++d[u];
edge[cnt] = (Edge){u, first[v]}, first[v] = cnt++, ++d[v];
}

void Dfs(int u, int ff) {
int e, v, len, cur;
vis[u] = 1;
for (e = first[u]; ~e; e = edge[e].next)
if ((v = edge[e].to) ^ ff) {
if (!vis[v]) deep[v] = deep[u] + 1, fa[v] = u, Dfs(v, u);
else if (deep[v] < deep[u]) {
for (len = 1, cur = u; cur ^ v; cur = fa[cur]) ++len;
Dec(ans, (ll)Sub(1, inv2[len]) % mod);
}
}
}

int main() {
int i, u, v;
memset(first, -1, sizeof(first));
In(n), In(m);
inv2[0] = 1, inv2[1] = (mod + 1) >> 1;
for (v = m + m, i = 2; i <= v; ++i) inv2[i] = (ll)inv2[i - 1] * inv2[1] % mod;
for (i = 1; i <= m; ++i) In(u), In(v), AddEdge(u, v);
ans = Add(1, (ll)m * inv2[1] % mod), Dfs(1, 0);
for (i = 1; i <= n; ++i) Dec(ans, inv2[d[i]]);
ans = (ll)ans * Pow(2, m) % mod, printf("%d\n", ans);
return 0;
}

posted @ 2019-02-22 14:39  Cyhlnj  阅读(159)  评论(0编辑  收藏  举报