• LOJ6509 「雅礼集训 2018 Day7」C


    Link
    考虑计算出每个点除最后一步以外的期望到达次数,很显然初始同色点的这个值是相等的。
    (f_{i,0/1})表示在有(i)(1)时,颜色为(0/1)的点除最后一步以外的期望到达次数。
    那么可以列出转移方程:

    [egin{aligned} f_{i,0}&=frac inf_{i-1,0}+frac{n-i-1}nf_{i+1,0}+frac1nf_{i+1,1}+frac1n\ f_{i,1}&=frac{n-i}nf_{i+1,1}+frac{i-1}nf_{i-1,1}+frac1nf_{i-1,0}+frac1n end{aligned} ]

    利用第二个方程计算出(f_{i+1,1}),再利用第一个方程计算出(f_{i+1,0})即可完成递推。
    那么设(f_{1,0}=x,f_{1,1}=y)即可将所有的(f_{i,o})都用(ax+by+c)表示。
    最后联立两个方程解出(x,y)即可计算得到答案。

    #include<cctype>
    #include<cstdio>
    #include<vector>
    using i64=long long;
    const int N=100007,P=1000000007;
    char col[N];int n,fa[N],size[N];i64 inv[N],ans[N];
    std::vector<int>e[N];
    struct node
    {
        i64 a,b,c;
        node(int A=0,int B=0,int C=0):a(A),b(B),c(C){}
        void mod(){a+=a>>63&P,b+=b>>63&P,c+=c>>63&P;}
    }f[N][2];
    node operator+(const node a,const node b){return node(a.a+b.a,a.b+b.b,a.c+b.c);}
    node operator-(const node a,const node b){return node(a.a-b.a,a.b-b.b,a.c-b.c);}
    node operator*(const node a,const i64 b){return node(a.a*b%P,a.b*b%P,a.c*b%P);}
    node operator+(const node a,const i64 b){return node(a.a,a.b,a.c+b);}
    node operator-(const node a,const i64 b){return node(a.a,a.b,a.c-b);}
    int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
    i64 pow(i64 a,i64 b){a%=P;i64 r=1;for(;b;b>>=1,a=a*a%P)if(b&1)r=r*a%P;return r;}
    void dfs1(int u)
    {
        size[u]=1;
        for(int v:e[u]) if(v^fa[u]) dfs1(v),size[u]+=size[v],ans[u]+=ans[v]+size[v];
    }
    void dfs2(int u)
    {
        if(fa[u]) ans[u]=ans[fa[u]]+n-2*size[u];
        for(int v:e[u]) dfs2(v);
    }
    int main()
    {
        int cnt=0;
        n=read(),scanf("%s",col+1),inv[0]=inv[1]=f[1][0].a=f[1][1].b=1;
        for(int i=1;i<=n;++i) cnt+=col[i]=='1';
        for(int i=2;i<=n;++i) e[fa[i]=read()].push_back(i),inv[i]=(P-P/i)*inv[P%i]%P;
        dfs1(1),dfs2(1);
        for(int i=1;i<n;++i) f[i+1][1]=(f[i][1]*n-f[i-1][1]*(i-1)-f[i-1][0]-(i!=1))*inv[n-i],f[i+1][0]=(f[i][0]*n-f[i-1][0]*i-f[i+1][1]-1)*inv[n-i-1],f[i+1][0].mod(),f[i+1][1].mod();
        node a=f[n-1][1]*n-f[n-2][1]*(n-2)-f[n-2][0]-1,b=f[n-1][0]*n-f[n-2][0]*(n-1);
        i64 x=(b.b*a.c-b.c*a.b)%P*pow(a.b*b.a-a.a*b.b,P-2)%P,y=(b.a*a.c-b.c*a.a)%P*pow(a.a*b.b-a.b*b.a,P-2)%P,coef[2],Ans=0;
        for(int i=0;i<2;++i) coef[i]=(f[cnt][i].a*x+f[cnt][i].b*y+f[cnt][i].c+inv[n])%P;
        for(int i=1;i<=n;++i) (Ans+=ans[i]%P*coef[col[i]&15])%=P;
        printf("%lld",(Ans+P)*inv[n]%P);
    }
    
  • 相关阅读:
    起泡排序引申出的问题
    关于NPC和NP-Hard问题
    我的书单(更新中)
    OpenCV2学习笔记03:Qt中配置OpenCV环境
    Ubuntu 14.04为浏览器添加Flash插件
    CSS3基础
    HTML5进阶
    拖拽上传及读取文件实现
    生产者消费者模型
    进程
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12929180.html
Copyright © 2020-2023  润新知