#include using namespace std; // 素因数分解を行い、(素因数, 指数)のペアを返す関数 vector> primeFactorization(int N) { vector > res; // √N まで試し割っていく for (long long p = 2; p * p <= N; ++p) { // N が p で割り切れないならばスキップ if (N % p != 0) { continue; } // N の素因数 p に対する指数を求める int e = 0; while (N % p == 0) { // 指数を 1 増やす ++e; // N を p で割る N /= p; } // 答えに追加 res.emplace_back(p, e); } // 素数が最後に残ることがありうる if (N != 1) { res.emplace_back(N, 1); } return res; } int reconstructFromFactors(const vector>& factors) { int result = 1; for (const auto& factor : factors) { result *= (int)pow(factor.first, factor.second); } return result; } int computeTotient(const vector>& factors) { double result = 1.0; // 初期値をnに設定 for (const auto& factor : factors) { int p = factor.first; // 素因数 if(factor.second != 0){ result *= pow(factor.first,factor.second)*(1.0 - 1.0 / p); } } return static_cast(result); // 結果を整数に変換 } double fill_dp(vector> factors,vector dp){ int n = reconstructFromFactors(factors); if(dp[n] > -0.5){ return dp[n]; } int size = factors.size(); double sum_dp = 0.0; vector e(size,0); vector> k(size); vector> n_k(size); int k_num; e[0] = 1; for(int i=0;i factors[i].second){ e[i] = 0; e[i+1]++; } k[i].second = e[i]; n_k[i].second = factors[i].second - e[i]; } k[size-1].second = e[size-1]; n_k[size-1].second = factors[size-1].second - e[size-1]; } dp[n] = ((double)n + sum_dp)/((double)(n-1)); return dp[n]; } int main() { int N; cin >> N; clock_t start = clock(); vector> factors = primeFactorization(N); vector dp(N+1,-1.0); dp[1] = 1; cout << fill_dp(factors,dp) << endl; clock_t end = clock(); const double time = static_cast(end - start) / CLOCKS_PER_SEC * 1000.0; printf("time %lf[ms]\n", time); return 0; }