結果

問題 No.2829 GCD Divination
ユーザー rieaaddlreiuu
提出日時 2024-12-04 20:22:32
言語 C++14
(gcc 13.3.0 + boost 1.87.0)
結果
MLE  
実行時間 -
コード長 2,795 bytes
コンパイル時間 4,565 ms
コンパイル使用メモリ 174,828 KB
実行使用メモリ 557,156 KB
最終ジャッジ日時 2024-12-04 20:23:31
合計ジャッジ時間 59,030 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 7 WA * 12 TLE * 15 MLE * 1
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<bits/stdc++.h>
using namespace std;

// 素因数分解を行い、(素因数, 指数)のペアを返す関数
vector<pair<int, int>> primeFactorization(int n) {
    vector<pair<int, int>> factors;

    // 2で割り切れる限り割る
    int count = 0;
    while (n % 2 == 0) {
        count++;
        n /= 2;
    }
    if (count > 0) {
        factors.push_back({2, count});
    }

    // 3以上の奇数で割り切れる限り割る
    for (int i = 3; i * i <= n; i += 2) {
        count = 0;
        while (n % i == 0) {
            count++;
            n /= i;
        }
        if (count > 0) {
            factors.push_back({i, count});
        }
    }

    // nが素数の場合(1より大きい)
    if (n > 1) {
        factors.push_back({n, 1});
    }

    return factors;
}

int reconstructFromFactors(const vector<pair<int, int>>& factors) {
    int result = 1;
    for (const auto& factor : factors) {
        result *= (int)pow(factor.first, factor.second);
    }
    return result;
}

int computeTotient(int n, const vector<pair<int, int>>& factors) {
    double result = n; // 初期値をnに設定

    for (const auto& factor : factors) {
        int p = factor.first; // 素因数
        if(factor.second != 0){
            result *= (1.0 - 1.0 / p);
        }
    }

    return static_cast<int>(result); // 結果を整数に変換
}

double fill_dp(vector<pair<int,int>> factors,vector<double> dp){
    int n = reconstructFromFactors(factors);
    if(dp[n] > -0.5){
            return dp[n];
    }
    int size = factors.size();
    double sum_dp = 0.0;
    vector<int> e(size,0);
    vector<pair<int,int>> k(size);
    vector<pair<int,int>> n_k(size);
    int k_num;
    double totient = (double)n;
    e[0] = 1;
    while(e[size-1] <= factors[size-1].second){
        totient = (double)n;
        for(int i=0;i<size;i++){
            k[i].first = factors[i].first;
            k[i].second = e[i];
            n_k[i].first = factors[i].first;
            n_k[i].second = factors[i].second - e[i];
            if(factors[i].second != e[i]){
                totient = totient*(1.0-1.0/(double)factors[i].first);
            }
        }
        k_num = reconstructFromFactors(k);
        totient = totient / (double)k_num;
        if(k_num != n){
            sum_dp += totient * fill_dp(k,dp);
        }
        e[0]++;
        for(int i=0;i<size-1;i++){
            if(e[i] > factors[i].second){
                e[i] = 0;
                e[i+1]++;
            }
        }
    }
    dp[n] = ((double)n + sum_dp)/((double)(n-1));
    return dp[n];
}

int main() {
    int N;
    cin >> N;
    vector<pair<int,int>> factors = primeFactorization(N);
    vector<double> dp(N+1,-1.0);
    dp[1] = 1;
    cout << fill_dp(factors,dp) << endl;
    return 0;
}
0