
发现列个方程就可以了:
f(x)=1+ (not_div/tot)*f(x) + (1/tot) ∑f(x/div)
=> (div/tot)*f(x)=1 + (1/tot) ∑f(x/div)
=> f(x)=(tot/div) + (1/div) ∑f(x/div)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define maxn 1000000
using namespace std;
vector<int> g[maxn];
int v[maxn+5],T,n;
double f[maxn+5];
bool iscalc[maxn+5];
inline void init(){
for(int i=2;i<=maxn;i++) if(!v[i]){
g[i].pb(1);
for(int u=2,j=i<<1;j<=maxn;j+=i,u++) v[j]=1,g[j].pb(u);
}
iscalc[1]=1,f[1]=0;
for(int i=2;i<=maxn;i++) v[i]=v[i-1]+1-v[i];
}
inline double dp(int x){
if(iscalc[x]) return f[x];
iscalc[x]=1,f[x]=v[x];
int sz=g[x].size();
for(int i=0;i<sz;i++){
f[x]+=dp(g[x][i]);
}
f[x]/=(double)sz;
return f[x];
}
int main(){
init();
scanf("%d",&T);
for(int i=1;i<=T;i++){
scanf("%d",&n);
printf("Case %d: %.10lf
",i,dp(n));
}
return 0;
}