• BZOJ5473: 仙人掌


    传送门

    首先,所有连通块的个数的期望再减去每个点孤立的概率就是答案。
    (d_i) 表示 (i) 的度数,那么每个点孤立的概率为 (frac{1}{2^{d_i}})
    考虑计算所有连通块的个数的期望
    对于一棵树来说,每次删除一条边会使得连通块的个数 (+1),概率为 (frac{1}{2}),那么 (n-1) 条边的期望就是 (1+frac{n-1}{2})
    对于仙人掌来说,如果这次删的是环上第一个被删除的边,那么不会贡献答案,所以要减去在一个环上至少删除了一条边的概率,设长度为 (len),就要减去 (1-frac{1}{2^{len}})
    所以只要求出每个环就好了。

    # 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
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    python基础_字典_列表_元组考试_day4
    基本数据类型-列表_元组_字典_day4
    python基础-基本数据类型总结_整型(int)_字符型(str)_day3
    python基础-range用法_python2.x和3.x的区别
    python基础--基本数据类型考试_day3
    批量创建文件和修改文件
    批量建立用户及密码
    打印九九乘法表
    Error Code : 1456 Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine pro_app_rs_right_update···
    mysql 创建视图出现1349 View's SELECT contains a subquery in the FROM clause解决办法
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/10418269.html
Copyright © 2020-2023  润新知