Uva 11762 Race to 1

 

发现列个方程就可以了:

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\n",i,dp(n));
	}
	
	return 0;
}

  

posted @ 2018-02-12 12:16  蒟蒻JHY  阅读(140)  评论(2编辑  收藏  举报