結果

問題 No.2365 Present of good number
ユーザー InTheBloomInTheBloom
提出日時 2023-07-10 17:05:14
言語 D
(dmd 2.106.1)
結果
WA  
実行時間 -
コード長 3,302 bytes
コンパイル時間 2,801 ms
コンパイル使用メモリ 172,072 KB
実行使用メモリ 6,948 KB
最終ジャッジ日時 2024-09-12 23:41:26
合計ジャッジ時間 3,790 ms
ジャッジサーバーID
(参考情報)
judge2 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

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

ソースコード

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-2) * powOf2 % (MOD-2), MOD)
        * modpow(3, modpow(2, K/2, MOD-2) * powOf3 % (MOD-2), 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 modpow(a, x-1, 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