【2018/10/17测试T1】发电机

【题目】

内网传送门
外网传送门

【分析】

不是第一次接触期望了,但之前一直不懂,今天听课后感觉多多少少有点收获,就记一下

定义:试验中每次可能结果的概率乘以其结果的总和

一个经典的例子就是掷骰子,每个点数的概率都是 1 6 \frac{1}{6} ,那期望就是 1 6 ( 1 + 2 + 3 + 4 + 5 + 6 ) = 3.5 \frac{1}{6}*(1+2+3+4+5+6)=3.5

一个关于期望的重要性质:线性性,即 E ( X + Y ) = E ( X ) + E ( Y ) E(X+Y)=E(X)+E(Y)

然后让我们回到这道题吧

可以发现在 i i 点放置发电机的概率是 1 s i z e i \frac{1}{size_i} ,其中 s i z e i size_i i i 的子树的大小

由于期望的线性性,统计出每个点的 s i z e size ,然后用逆元求解然后求和即可

逆元用快速幂求的话要多套一个 l o g log ,因此不能用快速幂,要用线推

【代码】

#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 10000005
#define Mod 998244353
using namespace std;
int Read()
{
	int x=0;char c=getchar();
	while(!isdigit(c))  c=getchar();
	while(isdigit(c))  {x=(x<<1)+(x<<3)+(c^'0');c=getchar();}
	return x;
}
int inv[N],size[N],father[N];
int main()
{
//	freopen("f.in","r",stdin);
//	freopen("f.out","w",stdout);
	int n,i,ans=0;
	n=Read();
	//scanf("%d",&n);
	inv[1]=1;
	for(i=2;i<=n;++i)
	{
		father[i]=Read();
		//scanf("%d",&father[i]);
		inv[i]=1ll*(Mod-Mod/i)*inv[Mod%i]%Mod;
	}
	for(i=n;i>=1;--i)
	{
		size[i]++;
		size[father[i]]+=size[i];
		ans=(ans+inv[size[i]])%Mod;
	}
	printf("%d",ans);
//	fclose(stdin);
//	fclose(stdout);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/forever_dreams/article/details/83112148
今日推荐