結果

問題 No.2365 Present of good number
ユーザー InTheBloomInTheBloom
提出日時 2023-07-10 17:38:18
言語 D
(dmd 2.106.1)
結果
AC  
実行時間 2 ms / 2,000 ms
コード長 3,314 bytes
コンパイル時間 1,529 ms
コンパイル使用メモリ 172,316 KB
実行使用メモリ 6,944 KB
最終ジャッジ日時 2024-09-12 23:41:42
合計ジャッジ時間 2,628 ms
ジャッジサーバーID
(参考情報)
judge4 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
6,812 KB
testcase_01 AC 2 ms
6,944 KB
testcase_02 AC 1 ms
6,944 KB
testcase_03 AC 1 ms
6,940 KB
testcase_04 AC 2 ms
6,944 KB
testcase_05 AC 2 ms
6,940 KB
testcase_06 AC 2 ms
6,944 KB
testcase_07 AC 1 ms
6,940 KB
testcase_08 AC 2 ms
6,940 KB
testcase_09 AC 1 ms
6,940 KB
testcase_10 AC 2 ms
6,940 KB
testcase_11 AC 1 ms
6,944 KB
testcase_12 AC 2 ms
6,940 KB
testcase_13 AC 1 ms
6,940 KB
testcase_14 AC 2 ms
6,944 KB
testcase_15 AC 2 ms
6,940 KB
testcase_16 AC 2 ms
6,940 KB
testcase_17 AC 1 ms
6,944 KB
testcase_18 AC 2 ms
6,940 KB
testcase_19 AC 1 ms
6,940 KB
testcase_20 AC 1 ms
6,944 KB
testcase_21 AC 2 ms
6,944 KB
testcase_22 AC 1 ms
6,940 KB
testcase_23 AC 1 ms
6,944 KB
testcase_24 AC 1 ms
6,944 KB
testcase_25 AC 1 ms
6,940 KB
testcase_26 AC 1 ms
6,944 KB
testcase_27 AC 2 ms
6,944 KB
testcase_28 AC 1 ms
6,940 KB
testcase_29 AC 2 ms
6,940 KB
testcase_30 AC 2 ms
6,944 KB
testcase_31 AC 1 ms
6,940 KB
testcase_32 AC 1 ms
6,940 KB
testcase_33 AC 2 ms
6,944 KB
testcase_34 AC 2 ms
6,940 KB
testcase_35 AC 1 ms
6,940 KB
testcase_36 AC 1 ms
6,940 KB
testcase_37 AC 1 ms
6,940 KB
testcase_38 AC 1 ms
6,940 KB
testcase_39 AC 1 ms
6,944 KB
testcase_40 AC 2 ms
6,940 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import std;

void read(T...)(string S, ref T args) {
    auto buf = S.split;
    foreach (i, ref arg; args) {
        arg = buf[i].to!(typeof(arg));
    }
}

void main () {
    //*
    long N, K; readln.read(N, K);
    solve(N, K);
    // */

    /* test
    foreach (N; 2..100001) {
        solve(N, -1);
    }
    // */
}

void solve (long N, long K) {
    const MOD = 100_000_000_7;

    long powOf2 = 0;
    long powOf3 = 0;
    while (true) {
        // break条件
        if (N == 1 || K == 0) {
            break;
        }

        // 2冪3冪だけの処理
        long tmp = powOf2;
        powOf2 = 2*powOf3;
        powOf3 = tmp;

        N = f(N, powOf2, powOf3);
        K--;
    }

    long ans = 0;

    // 復元+出力
    if (K == 0) {
        ans = N % MOD;
        ans *= modpow(2, powOf2, MOD);
        ans %= MOD;
        ans *= modpow(3, powOf3, MOD);
        ans %= MOD;

        writeln(ans);
        return;
    }

    // 残りのKを処理 2手で指数が全部二倍になる

    // 一回進める
    if (K % 2 == 1) {
        long tmp = powOf2;
        powOf2 = 2*powOf3;
        powOf3 = tmp;
        K--;
    }

    ans = modpow(2, (modpow(2, K/2, MOD-1) * powOf2) % (MOD-1), MOD)
        * modpow(3, (modpow(2, K/2, MOD-1) * powOf3) % (MOD-1), MOD);
    ans %= MOD;

    writeln(ans);
}

long modpow (long a, long x, const long MOD) {
    assert(0 <= a);
    assert(0 <= x);

    // base case
    if (x == 0) {
        return 1L;
    }
    if (x == 1) {
        return a % MOD;
    }

    // recursive case
    if (x % 2 == 0) {
        auto res = modpow(a, x/2, MOD);
        return res*res % MOD;
    } else {
        return a*modpow(a, x-1, MOD) % MOD;
    }
}

long f (long A, ref long powOf2, ref long powOf3) {
    auto x = Factors(A);
    long res = 1;
    foreach (i; 0..x.factor.length) {
        if (x.factor[i] == 1) {
            continue;
        }

        if (x.factor[i] == 2) {
            powOf3 += x.pow[i];
        } else if (x.factor[i] == 3) {
            powOf2 += 2 * x.pow[i];
        } else {
            res *= (x.factor[i] + 1) ^^ x.pow[i];
        }
    }
    return res;
}

struct Factors {
    long target;
    long[] factor;
    long[] pow;
    bool is_prime () {
        if (target <= 0) {
            return false;
        }
        if (factor.length == 2 && pow[1] == 1) {
            return true;
        }
        return false;
    }
    long[] combine_factor () {
        if (target <= 0) {
            return [];
        }
        long[] ret;
        foreach (i, x; pow) {
            foreach (k; 0..x) {
                ret ~= factor[i];
            }
        }
        return ret;
    }

    this (long target_) {
        { // check input
            assert(0 < target_);
        }
        target = target_;
        factor = [];
        pow = [];

        pow ~= 1;
        factor ~= 1;

        foreach (i; 2..target_) {
            if (target_ < i*i) {
                break;
            }
            if (target_ % i == 0) {
                factor ~= i;
                pow ~= 0;
                while (target_ % i == 0) {
                    target_ /= i;
                    pow[$-1]++;
                }
            }
        }
        if (target_ != 1) {
            factor ~= target_;
            pow ~= 1;
        }
    }
}
0