素数と乗算(数学、素数) - #589(DIV 2)CラウンドCodeforces

リンク:

https://codeforces.com/contest/1228/problem/C

質問の意味:

さんが後で必要になるいくつかの定義をご紹介しましょう。

プライム(x)は、xの素因子の集合とします。例えば、プライム(140)= {2,5,7-}、プライム(169)= {13}。

G(X、P)は、kは、xがPKで割り切れるような整数である最大可能整数PKとします。例えば:

G(45,3)= 9、(45 32 = 9で割り切れるが、33 = 27で割り切れない)
、G(63,7)= 7(63 71 = 7で割り切れるが、72 = 49で割り切れません)。
F(x、y)が素数で全てP(X)はGの生成物(Y、P)とします。例えば:

F(30,70)= G(70,2)⋅g(70,3)⋅g(70.5)=21⋅30⋅51= 10、
F(525,63)= G(63,3)⋅ G(63,5)⋅g(63,7)=32⋅50⋅71= 63。
あなたは、整数xとnを持っています。F(X、1)⋅f(X、2)⋅...⋅f(X、N)MOD(109 + 7)を計算します。

アイデア:

nは中の製品の!和。計算された程度のxのすべての素数については、
各素数pのために、取得するために素数Xの周りには、N / Pにおけるn!のメモリ内の^ 1、N / P ^ 2 ....カウントはあなたが数えることができるすべてながら、背後に蓄積し続けたときからです。
高速電力最適化。

コード:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MOD = 1e9+7;

vector<int> Pri;

void Init(LL val)
{
    for (LL i = 2;i*i <= val;i++)
    {
        if (val%i == 0)
            Pri.push_back(i);
        while (val%i == 0)
            val /= i;
    }
    if (val != 1)
        Pri.push_back(val);
}

LL Cal(LL val, int p)
{
    //素数p在val的阶乘下的次方贡献
    LL cnt = 0;
    while (val)
    {
        cnt += val/p;
        val /= p;
    }
    return cnt;
}

LL QucikMi(LL a, LL b)
{
    LL res = 1;
    while (b)
    {
        if (b&1)
            res = (res*a)%MOD;
        a = (a*a)%MOD;
        b >>= 1;
    }
    return res;
}

int main()
{
    LL x, n;
    cin >> x >> n;
    Init(x);
    LL res = 1;
    for (int i = 0;i < Pri.size();i++)
    {
        LL cnt = Cal(n, Pri[i]);
        res = (res*(QucikMi(Pri[i], cnt)))%MOD;
    }
    cout << res%MOD << endl;

    return 0;
}

おすすめ

転載: www.cnblogs.com/YDDDD/p/11619736.html