CF1823F 题解

CF1823F

思路

fu 表示经过 u 的期望次数。fu 的值是所有与 u 有边的点 v 的答案 fv 除以走向 u 的概率 1dv

fu=[u=s]+(u,v)E,vtfvdv

ft=1

问题是 fu 的值可以从 fa 得来,转移成环。直接高斯消元 O(n3),但是没有用到树的性质。成环是因为有来自父亲的转移,但根节点没有。设 fu=au×ffa+bu,带入 dp 方程。

fu=[u=s]+ffadfa+(u,v)E,vt,vfafvdv

fu=[u=s]+ffadfa+(u,v)E,vt,vfaav×fu+bvdv

(1(u,v)E,vt,vfaavdv)×fu=[u=s]+ffadfa+(u,v)E,vt,vfabvdv

fu=1dfa(1(u,v)E,vt,vfaavdv)×ffa+[u=s]+(u,v)E,vt,vfabvdv(1(u,v)E,vt,vfaavdv

对比系数,只与 u 的儿子有关,解出 au,bu。再从跟从上往下推一遍。注意到 vt 很烦,直接把 t 设为跟。

code

int n,s,t;
int head[maxn],tot;
struct nd{
	int nxt,to;
}e[maxn<<1];
void add(int u,int v){e[++tot]={head[u],v};head[u]=tot;}
inline int ksm(int a,int b=mod-2){
	int ans=1;
	while(b){
		if(b&1)ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans;
}
int d[maxn],f[maxn],a[maxn],b[maxn];
void dfs(int u,int fa){
	int val=1;b[u]=(u==s);
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;if(v==fa)continue;
		dfs(v,u);
		val+=mod-a[v]*ksm(d[v])%mod;
		b[u]+=b[v]*ksm(d[v])%mod;
	}
	val%=mod;b[u]%=mod;
	a[u]=ksm(val*d[fa]%mod);if(fa==t)a[u]=0;
	b[u]=ksm(val)*b[u]%mod;
}
void dfs1(int u,int fa){
	f[u]=(a[u]*f[fa]+b[u])%mod;
	for(int i=head[u];i;i=e[i].nxt){
		int v=e[i].to;if(v==fa)continue;
		dfs1(v,u);
	}
}
void work(){
	n=read();s=read();t=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		add(u,v),add(v,u);
		++d[u],++d[v];
	}
	dfs(t,0);
	f[t]=1;dfs1(t,0);
	for(int i=1;i<=n;i++)printf("%lld ",f[i]);
}
posted @   yhddd  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示