CF1823F Random Walk 树上随机游走

Fi 为经过点 i 时的期望 , ini 为点 i 度数 , 我们易得 :

Ft=1Fs=1+Ffainfa+vViFvinvFu=Ffainfa+vViFvinv(u!=T||S)

我们发现 Fi 只和它的父亲和有直接相连的儿子有关 , 可以写成一个方程组 , 用高斯消元解决 , 时间复杂度是 O(N3)

不足以通过本题 , 但是本题有一个优秀的性质 , 即是这是在一棵树上,当我们来到叶子节点时 , 便可以求解其系数 , 接下来就可以从下向上的解出每一项系数

按照我们刚才所说的列出树上高斯消元套路式子 (poweredby @ckain) :

Fi=giFfa+ci

2,3 写成一个式子:

Fu=Ffainfa+vViFvinv+[u=S](u!=T)=Ffainfa+vVigvFu+cvinv+[u=S]=Ffainfa+vVigvinvFu+vVicvinv+[u=S]

移项得:

(1vVigvinv)Fu=Ffainfa+vVicvinv+[u=S](u!=T)

此时我们就可以得知 gi&ci 的式子了 ( 把左边除过去

时间复杂度 O(N)

贴个代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int rd(void){
	int s=0, f=1; char c=getchar();
	while(c<'0' || c>'9') {if(c=='-') f=0; c=getchar();}
	while(c>='0' && c<='9') {s=s*10+c-'0'; c=getchar();}
	return f? s:-s;
}
const int N=2e5+10,mod=998244353;
int n;
int S,T;
int f[N],g[N],c[N],in[N];
vector<int> edge[N];
inline int qpow(int b,int p){
	int res=1;
	while(p){
		if(p&1)res=res*b%mod;
		b=b*b%mod;
		p>>=1;
	}
	return res;
}
void dfs1(int x,int fa){
	int gv=0,cv=0; 
	for(int i:edge[x]){
		if(i==fa)continue;
		dfs1(i,x);
		gv+=g[i]*qpow(in[i],mod-2)%mod;gv%=mod;
		cv+=c[i]*qpow(in[i],mod-2)%mod;cv%=mod;
	}
	gv=(1-gv+mod)%mod;
	gv=qpow(gv,mod-2);
	cv+=(x==S);
	if(fa!=T)g[x]=qpow(in[fa],mod-2)*gv%mod;
	c[x]=cv*gv%mod;
}
void dfs2(int x,int fa){
	if(x!=T)f[x]=(g[x]*f[fa]%mod+c[x])%mod;
	for(int i:edge[x]){
		if(i==fa)continue;
		dfs2(i,x);
	}
}
signed main(){
	n=rd();S=rd();T=rd();
	for(int i=1;i<n;i++){
		int x=rd(),y=rd();
		in[x]++;in[y]++;
		edge[x].push_back(y);
		edge[y].push_back(x);
	}
	dfs1(T,0);
	f[T]=1;
	dfs2(T,0);
	for(int i=1;i<=n;i++)printf("%lld ",f[i]);
	return 0;
}

posted @   Linnyx  阅读(77)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示