题意:
给出一个数字D
我们可以选择1-D中可以被D整除的数字,然后用D出得到一个新的数字D‘;
然后在找所有D’的因子,用D‘除,直到得到1;
给出一个数字D
我们可以选择1-D中可以被D整除的数字,然后用D出得到一个新的数字D‘;
然后在找所有D’的因子,用D‘除,直到得到1;
问除的次数的期望值
设一个数的约数有m个,E[n] = E[a[1]]/m+E[a[2]]/m+...+E[a[m]]/m+1 (因为又除一次,所以+1)
整理得:E[n]=(E[a[1]]+E[a[2]]+...+E[a[m-1]]+m)/(m-1)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define maxn 100009
using namespace std;
int vis[maxn], n;
double dp[maxn];
void dfs (int x)
{
if (x == 1)
{
dp[1] = 0.0;
vis[1] = 1;
return;
}
if (vis[x])
return;
vis[x] = 1;
double tot = 1.0;
int num = 0;
for (int i = 1; i * i <= x; i++)
if (x % i == 0)
{
num += i * i == x ? 1 : 2;
if (vis[i] == 0)
dfs (i);
if (i * i != x)
if (vis[x / i] == 0)
dfs (x / i);
if (i * i != x)
tot += dp[x / i];
tot += dp[i];
}
//printf ("dfs %d %d\n", x, num);
dp[x] = tot / (1.0 * (num - 1) ) + 1.0;
//printf ("%.3lf\n", dp[x]);
}
int main ()
{
int ti;
cin >> ti;
rep (Time, 1, ti)
{
memset (vis, 0, sizeof (vis));
memset (dp, 0, sizeof (dp));
scanf ("%d", &n);
dfs (n);
printf ("Case %d: %.10f\n", Time, dp[n]);
}
return 0;
}