Race to 1 Again LightOJ - 1038
对于一个整数 D D D,每次从他的因数中选一个 d d d,然后令 D = D / d D=D/d D=D/d,直到 D = 1 D=1 D=1 为止,问从 D D D 到 1 1 1 执行这样操作的期望次数。
用 E [ i ] E[i] E[i] 表示整数 i i i 变为 1 1 1 的期望次数, n n n 表示因子的总个数, a [ k ] a[k] a[k] 表示第 k k k 个因子,第 1 1 1 个因子 a [ 1 ] = 1 a[1]=1 a[1]=1,第 n n n 个因子 a [ n ] = i a[n]=i a[n]=i,则:
E [ i ] = 1 n ∑ k = 1 n ( E [ a [ k ] ] + 1 ) E [ i ] = E [ i ] n + 1 n ∑ k = 2 n − 1 E [ a [ k ] ] + 1 n − 1 n E [ i ] = 1 n ∑ k = 2 n − 1 E [ a [ k ] ] + 1 E [ i ] = 1 n − 1 ( ∑ k = 2 n − 1 E [ a [ k ] ] + n ) \begin{aligned} E[i]&=\frac{1}{n}\sum_{k=1}^n(E[a[k]]+1)\\ E[i]&=\frac{E[i]}{n}+\frac{1}{n}\sum_{k=2}^{n-1}E[a[k]]+1\\ \frac{n-1}{n}E[i]&=\frac{1}{n}\sum_{k=2}^{n-1}E[a[k]]+1\\ E[i]&=\frac{1}{n-1}(\sum_{k=2}^{n-1}E[a[k]]+n)\\ \end{aligned} E[i]E[i]nn−1E[i]E[i]=n1k=1∑n(E[a[k]]+1)=nE[i]+n1k=2∑n−1E[a[k]]+1=n1k=2∑n−1E[a[k]]+1=n−11(k=2∑n−1E[a[k]]+n)
代码如下:
#include<iostream>
#include<cstdio>
//#define WINE
#define MAXN 100010
using namespace std;
double d[MAXN];
int n,j,T,iCase;
int main(){
#ifdef WINE
freopen("data.in","r",stdin);
#endif
d[0]=d[1]=0;
for(int i=2;i<MAXN;i++){
n=0;
for(j=2;j*j<i;j++){
if(i%j==0){
n+=2;
d[i]+=d[j];
d[i]+=d[i/j];
}
}
if(j*j==i){
n+=1;
d[i]+=d[j];
}
n+=2;// 1 and i
d[i]+=n;
d[i]/=(n-1);
}
scanf("%d",&T);
while(T--){
scanf("%d",&n);
printf("Case %d: %.6lf\n",++iCase,d[n]);
}
return 0;
}