1. 程式人生 > 其它 >ABC F - Graph Smoothing 題解

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;
}