zoukankan      html  css  js  c++  java
  • 51Nod1679 连通率

    题目看这里

    一个简单的计数问题

    我们先考虑O(n^2)的做法

    对每个点dfs一次,求出d[i]表示i的深度,那么对答案贡献就是Σ2^(n-d[i])

    那么我们考虑用数据结构动态维护这个d[i],显然可以用线段树来维护dfs序做到

    复杂度O(n lg n) 效率很高rank8


    看了下solution突然才发现别人都不是这么做的!


    不管了反正跑得过而且跑的快。。就是代码比较丑陋

    #pragma GCC opitmize("O3")
    #pragma G++ opitmize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define M 1000000007
    #define LL long long
    #define mid (l+r>>1)
    #define N 100010
    using namespace std;
    const int inv=500000004;
    struct edge{ int v,nt; } G[N<<1];
    int n,cnt=0,h[N],w[N],t,d[N],l[N],r[N]; LL s[N<<2],c[N<<2],ans=0;
    inline void ad(LL& x,LL y){ x=(x+y)%M; }
    inline void mul(LL& x,LL y){ x=x*y%M; }
    inline LL pow(LL x,LL k,LL s=1){
        for(;k;x=x*x%M,k>>=1) k&1?s=s*x%M:0;
        return s;
    }
    inline void build(int l,int r,int x){
        if(l==r){ s[x]=pow(2,n-d[w[l]]-1); c[x]=1; return; }
        build(l,mid,x<<1);
        build(mid+1,r,x<<1|1);
        s[x]=(s[x<<1]+s[x<<1|1])%M; c[x]=1;
    }
    inline void pd(int x){
        if(c[x]>1){
            mul(c[x<<1],c[x]);
            mul(c[x<<1|1],c[x]);
            mul(s[x<<1],c[x]);
            mul(s[x<<1|1],c[x]);
            c[x]=1;
        }
    }
    inline void update(int l,int r,int x,int L,int R,LL k){
        if(L<=l && r<=R){ mul(s[x],k); mul(c[x],k); return; }
        pd(x);
        if(L<=mid) update(l,mid,x<<1,L,R,k);
        if(mid<R) update(mid+1,r,x<<1|1,L,R,k);
        s[x]=(s[x<<1]+s[x<<1|1])%M;
    }
    inline LL query(int l,int r,int x,int L,int R){
        if(L<=l && r<=R) return s[x];
        pd(x); LL ans=0;
        if(L<=mid) ad(ans,query(l,mid,x<<1,L,R));
        if(mid<R) ad(ans,query(mid+1,r,x<<1|1,L,R));
        return ans;
    }
    inline void dfs(int x){
        w[++t]=x; l[x]=t;
        for(int v,i=h[x];i;i=G[i].nt)
            if(!l[v=G[i].v]){ d[v]=d[x]+1; dfs(v); }
        r[x]=t;
    }
    inline void cal(int x,int p){
        ad(ans,query(1,n,1,1,n));
        for(int v,i=h[x];i;i=G[i].nt)
            if((v=G[i].v)!=p){
                update(1,n,1,l[v],r[v],4);
                update(1,n,1,1,n,inv);
                cal(v,x); 
                update(1,n,1,l[v],r[v],(LL)inv*inv%M);
                update(1,n,1,1,n,2);
            }
    }
    int main(){
        scanf("%d",&n);
        for(int x,y,i=1;i<n;++i){
            scanf("%d%d",&x,&y);
            G[++cnt]=(edge){y,h[x]}; h[x]=cnt;
            G[++cnt]=(edge){x,h[y]}; h[y]=cnt;
        }
        dfs(1);
        build(1,n,1);
        cal(1,0);
        ad(ans,-n*pow(2,n-1)%M);
        printf("%lld
    ",(ans+M)%M*inv%M);
    }

  • 相关阅读:
    1,300萬像素Xperia TX K.O.相機 東方日報
    信息检索Reading List
    雷军:小米二为何不用1300万像素相机_TechWeb
    1300万像素高清双核旗舰 索尼LT30p评测_手机_科技时代_新浪网
    Darts: DoubleARray Trie System海 的 声音我的搜狐
    说说底层架构之实体类的设计
    不忘本~枚举
    两种底层数据层操作时的架构方式,你喜欢那种?
    说说C#中的global
    JS对外部文件的加载及对IFRMAME的加载的实现,当加载完成后,指定指向方法(方法回调)
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/8511187.html
Copyright © 2011-2022 走看看