zoukankan      html  css  js  c++  java
  • ABC F Graph Smoothing 题解

    F - Graph Smoothing

    给出一张图,\(N\) 个点 \(M\) 条边,每个点有一个初始权值 \(a_i\)

    接下来有 \(K\) 次操作,每次相互独立

    • 随机选中一条边 \(<u,v>\),将 \(a_u\)\(a_v\) 修改成\((a_u+a_v)/2\)

    求出最后每个点的期望大小

    solve

    分别考虑 \(a_i\) 对自己的影响和其他的影响

    \(d_i\)\(i\) 的度

    • 自己最自己影响

    对于一个点,本来对他自己的贡献是 \(a_i\) ,但是由于和他连接的有 \(d_i\) 条边,所以他们被选中的概率是 \(d_i\over m\),每一条边被选中,这个点 的贡献会从本来的 \(a_i\) 变成 \(a_i\over 2\),所以用 \(1\) 减去少掉的贡献,所以自己对自己的贡献就是 \(a_i\times (1-{d_i\over {m\times 2}})\)

    所以概率矩阵 \(a[i][i]= 1-{d_i\over {m\times 2}}\)

    • 和自己连边的点对自己的贡献

    对于任意一条边 \(<u,v>\),显然选择到该边的概率为 \(1\over m\) ,一条边对自己的概率的影响是 \(1\over m\) ,所以概率矩阵 \(a[i][j]=1\over{2\times m}\)

    剩下的就是矩阵快速幂,算出 \(k\) 时刻的期望,乘上 \(a_i\)就是期望了

    code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int maxn=105;
    const LL TT=1e9+7;
    int N,du[maxn],M,K,a[maxn];
    LL ans;
    struct Matrix{
    	int V[maxn][maxn];
    	Matrix(){memset(V,0,sizeof V);}
    	friend Matrix operator *(Matrix A,Matrix B){
    		Matrix C;
    		for(int i=1;i<=N;i++)
    			for(int j=1;j<=N;j++)
    				for(int k=1;k<=N;k++)
    					C.V[i][j]=(C.V[i][j]+1LL*A.V[i][k]*B.V[k][j])%TT;
    		return C;
    	}
    }E,G;
    inline int read(){
    	int ret=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    	while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    	return ret*f;
    }
    int Pow(int a,int b){
    	int s=1,w=a;
    	while(b){
    		if(b&1)s=1LL*s*w%TT;w=1LL*w*w%TT;b>>=1;
    	}
    	return s;
    }
    int main(){
    	freopen("F - Graph Smoothing.in","r",stdin);
    	freopen("F - Graph Smoothing.out","w",stdout);
    	N=read();M=read();K=read();
    	for(int i=1;i<=N;i++) a[i]=read();
    	for(int i=1;i<=M;i++){
    		int x=read(),y=read();
    		E.V[x][y]=E.V[y][x]=1;
    		du[x]++;du[y]++;
    	}
    	int Inv_2m=Pow(2*M,TT-2);
    	for(int i=1;i<=N;i++){
    		for(int j=1;j<=N;j++)if(E.V[i][j]) E.V[i][j]=Inv_2m;
    		E.V[i][i]=(1ll*2*M-du[i])*Inv_2m%TT;
    	}
    	for(int i=1;i<=N;i++) G.V[i][i]=1;
    	while(K){
    		if(K&1) 
    			G=G*E;
    		E=E*E;
    		K>>=1;
    	}
    	for(int i=1;i<=N;i++){
    		ans=0;
    		for(int j=1;j<=N;j++)
    			ans=(ans+(1ll*G.V[j][i]*a[j])%TT)%TT;
    		printf("%lld\n",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    qt学习笔记(1):qt点击运行没有反应。
    JS Object类型
    JS Boolean数据类型和数据类型转换规律
    CSS雪碧图
    CSS
    PS基础
    JS number数字类型
    js中的变量和数据类型
    JS 基础
    单词
  • 原文地址:https://www.cnblogs.com/martian148/p/15531945.html
Copyright © 2011-2022 走看看