复习之求一个数的约束之积模一个质数

  首先我们知道对于一个数x, 他的约数之积可以表示为f(x) = x^(d(x)/2)  其中d(x)为x的约束的个数。 当x很大的时候d(x)会变的非常大,很难将确切的d(x)算出来, 费马小定理告诉我们当p是质数的时候a^p = a(mod p), 当a与p互质的时候式子就变成了a^p-1 = 1 (mod p), 通过这个我们可以对d(x)取模从而简化计算。现在我们考虑两个数a与b互质,

d(ab) = d(a)*d(b), f(ab) = f(a)^d(b) * f(b)^d(a), f(pi^ai) = pi^(ai*(ai+1))/2, 有了这个公式, 我们将x化为唯一分解式之后很快就能解决。代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>

using namespace std;
typedef long long LL;
const LL MOD = 1000000007;

int pi[100], ai[100];
int len;

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


int main()
{
    cin>>len;
    for(int i=0; i<len; i++)
    {
        cin>>pi[i]>>ai[i];
    }
    LL fa=1, da=1;
    for(int i=0; i<len; i++)
    {
        LL fb = powmod(pi[i], (ai[i]+1)*ai[i]/2);
        LL db = ai[i]+1;
        fa = powmod(fa, db)*powmod(fb, da)%MOD;
        da = (da*db)%(MOD-1);
    }
    cout<<fa<<endl;
    return 0;
}

 

你可能感兴趣的:(复习之求一个数的约束之积模一个质数)