题解:CF1823F Random Walk
集训出的神秘东西。
设
显然每次走到
于是可以列出以下柿子。
-
f_t=1 -
\displaystyle f_s=1+\sum_{(s,v)\in E,v\ne t}\frac{1}{d_v}f_v -
\displaystyle f_u=\sum_{(u,v)\in E,v\ne t}\frac{1}{d_v}f_v
其中
:::info[解释]
第一条显然,因为到
第三条也容易推出来,
第二条类似,只是
似乎高斯消元可以做了?但是复杂度是
这里用到随机游走题目的一个通用做法:将
刚才推出,对于一般的
也就是说,
注意到这里的
也就是说,
代入上面的柿子,
于是
再把左边的系数除过去就变成了
这样下来,我们把所有的
:::success[code]
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
#define inv(x) qpow(x,mod-2)
const int N=2e5+10,mod=998244353;
vector<pair<int,int>>adj[N];
int n,s,t,f[N],a[N],b[N],ta[N],tb[N];
int qpow(int a,int b)
{
int s=1;
while(b)
{
if(b&1) s=s*a%mod;
a=a*a%mod;
b>>=1;
}
return s;
}
void dfs1(int u,int fa)
{
for(auto& v:adj[u])
{
if(v.fi==fa) continue;
dfs1(v.fi,u);
if(v.fi!=t) v.se=inv(adj[v.fi].size());
}
if(fa&&fa!=t) ta[u]=inv(adj[fa].size());
if(u==s) tb[u]=1;
else if(u==t)
{
ta[u]=0,tb[u]=1;
for(auto& v:adj[u])
{
if(v.fi==fa) continue;
v.se=0;
}
}
}
void dfs2(int u,int fa)
{
a[u]=0,b[u]=tb[u];
for(auto v:adj[u])
{
if(v.fi==fa) continue;
dfs2(v.fi,u);
a[u]=(a[u]+a[v.fi]*v.se%mod)%mod;
b[u]=(b[u]+b[v.fi]*v.se%mod)%mod;
}
int x=inv((1-a[u]+mod)%mod);
a[u]=ta[u]*x%mod;
b[u]=b[u]*x%mod;
}
void dfs3(int u,int fa)
{
f[u]=(a[u]*f[fa]%mod+b[u])%mod;
for(auto v:adj[u])
{
if(v.fi==fa) continue;
dfs3(v.fi,u);
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>s>>t;
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
adj[u].push_back({v,0});
adj[v].push_back({u,0});
}
dfs1(1,0);
dfs2(1,0);
dfs3(1,0);
for(int i=1;i<=n;i++) cout<<f[i]<<' ';
return 0;
}
:::