2021陕西省赛 D.Disease(树形dp&期望dp)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021陕西省赛 D.Disease(树形dp&期望dp)相关的知识,希望对你有一定的参考价值。
2021陕西省赛 D.Disease(树形dp&期望dp)
因为是求最小等级的期望,因此不需要往下考虑。
先树形dp计算每个结点不被感染的概率。
然后利用差分的思想。
对于答案为第 i i i层的贡献就是前 i − 1 i-1 i−1层没被感染的概率减取前 i i i层没被感染的概率。
前 i i i层没被感染的概率就是前 i − 1 i-1 i−1都没被大自然感染,且第 i i i层的所有结点不被感染。
代码
#include <cstdio>
#include <iostream>
#define ll long long
using namespace std;
const int N=2e5+50;
const ll mod=1e9+7;
ll fpow(ll x,ll k)
ll ans=1;x=(x+mod)%mod;
while(k)
if(k&1) ans*=x,ans%=mod;
x*=x;x%=mod;
k>>=1;
return ans%mod;
ll divd(ll a,ll b)
return (a%mod)*(fpow(b,mod-2)%mod)%mod;
struct edge
int u,v;
ll p;
edge(int x,int y,ll a):u(x),v(y),p(a)
edge()
e[N<<1];
int front[N],nxt[N<<1],en,n,dep=0;
ll pt[N],dp[N],d[N];
inline void add(int u,int v,ll p)
e[++en].u=u;e[en].v=v;e[en].p=p;
nxt[en]=front[u];front[u]=en;
void dfs(int p,int fa)
ll ans=1-pt[p]+mod;ans%=mod;
for(int eg=front[p];eg;eg=nxt[eg])
if(e[eg].v!=fa)
dfs(e[eg].v,p);
ans*=(dp[e[eg].v]+((1-dp[e[eg].v]+mod)%mod*((1-e[eg].p+mod)%mod)%mod))%mod;
ans%=mod;
dp[p]=ans;
return ;
ll sum[N],s[N];
void dfs1(int p,int fa,int depth)
dep=max(dep,depth);
d[depth]=d[depth]*dp[p]%mod;
s[depth]=s[depth]*((1-pt[p]+mod)%mod)%mod;
for(int eg=front[p];eg;eg=nxt[eg])
if(e[eg].v!=fa) dfs1(e[eg].v,p,depth+1);
int main()
int x,y;
ll a,b,ans;
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%lld%lld",&a,&b),pt[i]=divd(a,b);
for(int i=1;i<n;++i)
scanf("%d%d%lld%lld",&x,&y,&a,&b);
add(x,y,divd(a,b));add(y,x,divd(a,b));
dfs(1,1);
for(int i=1;i<=n;++i) s[i]=d[i]=1;
dfs1(1,1,1);
sum[0]=1;
for(int i=1;i<=n;++i) sum[i]=s[i]*sum[i-1]%mod;
ans=1-dp[1]+mod;ans%=mod;
for(int i=2;i<=dep;++i)
ll dx=i;
// 前i-1层: sum[i-2]*d[i-1]
//前i层: sum[i-1]*d[i]=sum[i-1]*s[i]*d[i]
ans+=dx*sum[i-2]%mod*((d[i-1]-s[i-1]*d[i]%mod+mod)%mod)%mod;
ans%=mod;
printf("%lld\\n",ans);
return 0;
以上是关于2021陕西省赛 D.Disease(树形dp&期望dp)的主要内容,如果未能解决你的问题,请参考以下文章
2019 沈阳网络赛 D Fish eating fruit ( 树形DP)