bzoj3566 SHOI2014 概率充電器

2021-07-10 14:38:03 字數 3422 閱讀 9634

n個充電器連成一棵樹。

第i個充電器有p[i]的概率直接充電。

每條導線有一定機率可以導電。

可以導電的導線形成的聯通塊中只要存在直接充電的結點整個聯通塊的充電器均進入充電狀態。

問期望進入充電狀態的充電器個數

顯然可知我們只需要得到f[i]表示i進入充電狀態的概率 那麼a

ns=∑

f[i]

我們把無根樹變有根樹。 設a

[i]=

p(i與

i的父親

不連通)

+p(i

與i父親

連通)∗

p(只考

慮以i為

根的子樹

的充電器

的充電情

況i未進

入充電狀

態)即a[i]表示i的父親不因為i而進入充電狀態的概率。

我們設g[i

]=p(

只考慮以

i為根的

子樹的充

電器的充

電情況i

進入充電

狀態)

則 g[i

]=p(

i直接進

入充電狀

態)+[

1−p(

i直接進

入充電狀

態)]∗

p(i的

至少乙個

連通兒子

在只考慮

以其為根

的子樹的

充電情況

下進入充

電狀態)

g[i]=p[

i]+(

1−p[

i])∗

(1−p

(i的所

有兒子要

麼不連通

要麼連通

但只考慮

以其為根

的子樹的

充電情況

下未進入

充電狀態

)) g

[i]=

p[i]

+1−p

[i]−

(1−p

[i])

∗∏j是

i兒子p

(j要麼

不連通要

麼連通但

只考慮以

j為根的

子樹的充

電情況下

j未進入

充電狀態

) g[

i]=1

−(1−

p[i]

)∗∏j

是i兒子

a[j]

現在我們有了g我們需要算出f,不如再設乙個輔助陣列b。 b[

i]=p

(在不考

慮以i為

根的子樹

的充電情

況下i的

父親進入

充電狀態

) 相當於刪去i與其父親的連邊後的f』[i的父親]。

我們知道 g[

i]=1

−(1−

p[i]

)∗∏j

是i兒子

a[j]

1−g[i]=

(1−p

[i])

∗∏j是

i兒子a

[j]

那麼如果設x=

1−1−

g[i]

a[j]

那x表示的就是刪除i與j的連邊後按照原來方法計算出的g』[i] 那麼b

[i]=

f′[i

的父親]

=g′[

i的父親

]+(1

−g′[

i的父親

])∗p

(刪除i

爺爺與i

父親的連

邊後i爺

爺進入充

電狀態)

∗p(i

爺爺與i

父親連通

) b[

i]=1

−1−g

[i的父

親]a[

i]+1

−g[i

的父親]

a[i]

∗b[i

的父親]

∗p(i

爺爺與i

父親連通

) 有了b就可以計算f了 f[

i]=g

[i]+

(1−g

[i])

∗b[i

]∗p(

i與i父

親連通)

兩遍dfs計算即可。

不過這題會爆棧!只能打人工棧……

注意一些小細節:比如分母為0直接賦值為0……

#include

#include

#define fo(i,a,b) for(i=a;i<=b;i++)

using namespace std;

typedef double db;

const int maxn=500000+10;

int h[maxn],now[maxn],go[maxn*2],next[maxn*2];

db dis[maxn*2];

db a[maxn],b[maxn],g[maxn],f[maxn],p[maxn],q[maxn];

struct dong;

dong sta[maxn],zlt;

int i,j,k,l,t,n,m,tot,top;

db ans;

void add(int

x,int

y,int z)

void dfs()

g[x]=1-(1-p[x])*l;

a[x]=1-q[x]+q[x]

*(1-g[x]);

top--;

continue;

}q[go[t]]=dis[t];

zlt.x=go[t];zlt.y=x;

sta[++top]=zlt;

now[x]=next[t];

}}void dg()

if (y&&a[x]) b[x]=1-(1-g[y])/a[x]+(1-g[y])/a[x]*q[y]*b[y];else b[x]=0;

f[x]=g[x]+(1-g[x])*q[x]*b[x];

t=h[x];

now[x]=0;

while (t)

t=next[t];}}

}int main()

fo(i,1,n)

fo(i,1,n) now[i]=h[i];

zlt.x=1;zlt.y=0;

sta[top=1]=zlt;

dfs();

fo(i,1,n) now[i]=1;

zlt.x=1;zlt.y=0;

sta[top=1]=zlt;

dg();

fo(i,1,n) ans+=f[i];

printf("%.6lf\n",ans);

}

BZOJ 3566 SHOI2014 概率充電器

題目 題意 給定樹形結構的n個元件,每個元件有一定概率自己充電,還有一定概率通過某條邊給其他元件充電,求充電的元件期望個數。n 500000 題解 樹形結構肯定能想到樹形dp,全樹對某點產生的貢獻一般可以通過一到兩遍樹形dp計算得出,本題所求期望等於每個元件被充電的概率之和。設f i 表示i被充電的...

bzoj3566 SHOI2014 概率充電器

著名的電子產品品牌 shoi 剛剛發布了引領世界潮流的下一代電子產品 概率充電器 採用全新奈米級加工技術,實現元件與導線能否通電完全由真隨機數決定 shoi 概率充電器,您生活不可或缺的必需品 能充上電嗎?現在就試試看吧 shoi 概率充電器由 n 1 條導線連通了 n 個充電元件。進行充電時,每條...

BZOJ3566 SHOI2014 概率充電器

bzoj luogu 很顯然的兩遍樹dp吧。設 f i 表示只考慮 i 的子樹,i 點沒有電的概率。f i q i prod f v 1 f v 1 p e 為了方便表示把後面那一坨記為 h v 即 h i f i 1 f i 1 p e 然後再記乙個 g i 表示 i 的父親不向 i 供電的概率,...