lightoj1054効率的な擬似コード(オイラー関数+除数関数)

トピック

物乞い nm すべての除数の合計はmodにあります 1 e 9 + 7 結果として;

アイデア

数学的知識点
nは次のように書くことができます n =pバツ11pバツ22 、その後 nm=pm x11pm x22
このようにして、次の式を使用して問題を解決できます。特定の数学については、上記のリンクを参照してください。ここで、xは1です。
σバツn =ri = 1p((a+ 1 x1pバツ1


int prime[10000];
void init() {
    bool mark[100000] = {
   
   false};
    for (int i = 2;i < 100000;++i) {
        if (!mark[i]) {
            prime[++prime[0]] = i;
            mark[i] = true;
            for (long long j = 1ll*i * i;j < 100000;j += i)
                mark[j] = true;
        }
    }   
}
long long calc(long long a, long long b) {
    long long ans;
    ans = QMOD(a, b) - 1;
    // 这个地方用的逆元
    ans = ans * QMOD(a - 1, MOD - 2) % MOD;
    while(ans < 0) ans += MOD;
    if (ans > MOD) ans %= MOD;
    return ans;
}
int main(int argc, const char * argv[])
{    
    // freopen("/Users/jamesqi/Desktop/in.txt","r",stdin);
    // freopen("/Users/jamesqi/Desktop/out.txt","w",stdout);
    // ios::sync_with_stdio(false);
    // cout.sync_with_stdio(false);
    // cin.sync_with_stdio(false);

    int kase;cin >> kase;
    init();
    while(kase--) {
        long long n, m;cin >> n >> m;
        vector<ii> buff;
        for (int i = 1;i <= prime[0] && prime[i] * prime[i] <= n;++i) {
            if (n % prime[i] == 0) {
                ii t(prime[i], 0);
                while(n % prime[i] == 0) {
                    n /= prime[i];
                    ++t.second;
                }
                buff.push_back(t);
            }
        }
        if (n > 1) buff.push_back(ii(n, 1));

        long long ans = 1ll;
        for (int i = 0;i < (int)buff.size();++i)
            ans = ans * calc(buff[i].first, buff[i].second*m + 1) % MOD;
        printf("Case %d: %lld\n", ++nCase, ans);
    }

    // showtime;
    return 0;
}

おすすめ

転載: blog.csdn.net/KIJamesQi/article/details/55099570